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; }

浙公网安备 33010602011771号