LeetCode152. 乘积最大子序列

题目

给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。

示例 1:

输入: [2,3,-2,4]
输出:6
解释: 子数组 [2,3] 有最大乘积 6。

示例 2:

输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

分析

方法一 暴力求解

求出所有连续子串的乘积,记录最大数字。虽然有些暴力但是还是可以通过。

时间复杂度on^2。

方法二

用三个变量,max curmax curmin 分别来 保存 最大乘积, 当前最大乘积, 当前最小乘积。

大概思路是这样的:遍历序列,每到一个位置都更新当前的最大乘积和最小成绩,更新最大乘积,即求出当前最优解。

计算最小乘积的意义在于,因为数字有正有负,所以最小乘积在乘上一个负数之后,就很有可能会变成一个最大乘积。

curmax = Max( nums[i], curmax*nums[i], curmin*nums[i])

curmin  = Min ( nums[i], curmax*nums[i], curmin*nums[i])

max = Max( max , curmax)

时间复杂度On

代码

// 方法一
class Solution {
    public int maxProduct(int[] nums) {
        int len = nums.length;
        if (len == 1) return nums[0];
        int max = Integer.MIN_VALUE;
        int[] dp = new int[len];
        for (int i = 0; i < len; i++) {
            dp[i] = nums[i];
            max = Math.max(max,nums[i]);
        }
        for (int i = 1; i < len; i++) {
            for (int j = 0; j+i < len && j < len; j++) {
                dp[j] = dp[j]*nums[j+i];
                max = Math.max(max,dp[j]);
            }
        }
        return max;
    }
}
//方法二
class Solution {
    public int maxProduct(int[] nums) {
        int max = nums[0];
        int curmax = nums[0];
        int curmin = nums[0];

        for (int i = 1; i < nums.length; i++) {
            int nextmax = nums[i] * curmax;
            int nextmin = nums[i] * curmin;
            curmax = max(nums[i], nextmax, nextmin);
            curmin = min(nums[i], nextmax, nextmin);
            max = Math.max(max,curmax);
        }
        return max;
    }
    
    public static int max(int a , int b , int c){
        return Math.max(a,Math.max(b,c));
    }
    public static int min(int a, int b, int c){
        return Math.min(a,Math.min(b,c));
    }
    
}

猜你喜欢

转载自blog.csdn.net/qq_38595487/article/details/83786279
今日推荐