0
点赞
收藏
分享

微信扫一扫

数组中子数组的最大乘积(Java解法)

兮城 2022-04-08 阅读 177

目录

题目

[要求]

输入描述:

输出描述:

示例1

输入

输出

备注:

错误的思路分析:

错误原因:

改进后的思路:

样例推导:

代码展示:


题目

给定一个double类型的数组arr,其中的元素可正、可负、可0,返回子数组累乘的最大乘积。例如,arr=[-2.5, 4, 0, 3, 0.5, 8, -1],子数组[3, 0.5, 8]累乘可以获得最大的乘积12,所以返回12

[要求]

时间复杂度为O(N),空间复杂度为O(1)

输入描述:

第一行一个整数N。表示数组长度。 接下来一行N个浮点数表示数组内的数

输出描述:

输出一个浮点数表示答案,保留到小数点后两位

示例1

输入

7 -2.5 4 0 3 0.5 8 -1

输出

12.00

备注:

1 ≤ N ≤ Math.pow(10,5)

-100 ≤ arri ≤ 100

Math.pow(-10,22) ≤ 保证最后的答案 ≤ Math.pow(10,22)

错误的思路分析:

  1. 创建dp[n]一维数组
    1. 由于是子数组,所以dp[i]的含义是,以i结尾的子数组的最大值
  2. 初始化
    1. 如果数组长度=0,则返回1并退出
    2. 如果第一个数是负数,则dp[0]=1
    3. 如果是自然数,则dp[0]为该自然数数值
  3. 其余点:
    1. 如果当前数为0,则dp[i]=0
    2. 如果当前数为负数,
      1. 且dp[i-1]
      2. 否则dp[i] = arr[i]
    3. 如果当前数是正数
      1. 且dp[i-1]>0, dp[i] = dp[i-1]*arr[i]
      2. 否则d[i] = arr[i]
  4. 结果:
    1. dp中的最大值即为结果

错误原因:

不同于,加法,需要舍弃负数,这道题是子数组相乘。

子数组的最大累加和(java解法)

这道题看起来很简单,实则暗藏杀机,如果就按照上述方法这样写

会发现dp会将隐藏的负数宝藏给丢弃掉,也许此时负数没什么用,但也许在不久的将来,负数成负数,摇身一变,变成了最大值

就比如这个例子

arr = { 10,10,10,-1,-20}

如果按照上述思路写,答案会是(-1*10)= 20 ,但是之前的dp[4]如果为-1000,此时答案可以为20000

改进后的思路:

  1. 创建dp[n][2]二维数组,
    1. dp[i][0]的含义是,以i结尾的子数组的最大值
    2. dp[i][1]的含义是,以i结尾的子数组的最小值
  2. 初始化
    1. 如果数组长度=0,则返回1并退出
    2. dp[i][0] = dp[i][1] = arr[i]
  3. 其余点:
    1. 如果当前数为0,则dp[i][0] = dp[i][1] = 0
    2. dp[i][0] = arr[i], arr[i]*dp[i-1][0], arr[i]*dp[i-1][1] 三者中的最小值
    3. dp[i][0] = arr[i], arr[i]*dp[i-1][0], arr[i]*dp[i-1][1] 三者中的最大值
  4. 结果:
    1. dp中的最大值即为结果

样例推导:

代码展示:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(reader.readLine());
        double [] arr = new double[n];
        String[] str = reader.readLine().split(" ");
        for(int i=0;i<n;i++){
            arr[i] = Double.parseDouble(str[i]);
        }
        
        double [][] dp = new double[n][2];
        dp[0][0] = dp[0][1] = arr[0];
        double ans = 0;
        for(int i=1;i<n;i++){
            double p1 = arr[i];
            double p2 = arr[i] * dp[i-1][0];
            double p3 = arr[i] * dp[i-1][1];
            dp[i][0] = Math.max(p1, Math.max(p2, p3));
            ans = Math.max(ans, dp[i][0]);
            dp[i][1] = Math.min(p1, Math.min(p2, p3));
        }
        System.out.printf("%.2f", ans);
    }
}

空间压缩技巧:

import java.i.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(reader.readLine());
        double [] arr = new double[n];
        String[] str = reader.readLine().split(" ");
        for(int i=0;i<n;i++){
            arr[i] = Double.parseDouble(str[i]);
        }
        
        double dp00;
        double dp01;
        dp00 = dp01 = arr[0];
        double ans = 0;
        double p1,p2,p3;
        for(int i=1;i<n;i++){
            p1 = arr[i];
            p2 = arr[i] * dp00;
            p3 = arr[i] * dp01;
            dp00 = Math.max(p1, Math.max(p2, p3));
            ans = Math.max(ans, dp00);
            dp01 = Math.min(p1, Math.min(p2, p3));
        }
        System.out.printf("%.2f", ans);
    }
}

 

举报

相关推荐

0 条评论