No.152 乘积最大子数组

152. 乘积最大子数组 - 力扣(LeetCode) (leetcode-cn.com)

给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。


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

 

思路:拿到题,看着就像是要用动态规划。

首先想到的是,设置一个dp[]数组,dp[i]表示以nums[i]为结尾的一段数组的最大值,那么d[i] = Max(nums[i],  dp[i-1])。

可是,因为nums[]中负数的存在,假设nums[i]是负数,那么用nums[i] 与 前面的最值相乘,会使得最大变最小,最小变最大

于是,就需要同时维护dpmin[]和dpmax[]两个数组, 根据当前nums[i] 的正负,来更新dpmin[i]和dpmax[i]

 

 

注意: 在更新每一个位置的最值的时候,都需要让nums[i],也就是本身位置的数字纳入考虑范围,否则就会出现断档,从而导致结果不正确。

 

   public int maxProduct(int[] nums) {
        int len = nums.length;
        int[] dp_max = new int[len];
        dp_max[0] = nums[0];
        int[] dp_min = new int[len];
        dp_min[0] = nums[0];

        for(int i=1; i<len; i++){
            if(nums[i] >= 0){
                dp_max[i] = Math.max(nums[i], nums[i]*dp_max[i-1]);
                dp_min[i] = Math.min(nums[i], nums[i]*dp_min[i-1]);
            }
            else if(nums[i] < 0){
                dp_max[i] = Math.max(nums[i], nums[i]*dp_min[i-1]);
                dp_min[i] = Math.min(nums[i], nums[i]*dp_max[i-1]);
            }

        }
        int res = dp_max[0];
        for(int i=0; i<len ; i++){
            res = res < dp_max[i]? dp_max[i]:res;
        }
        return res;
    }

 

posted @ 2021-10-03 22:39  CharonKK  阅读(44)  评论(0)    收藏  举报