152. 乘积最大子数组

152 阅读1分钟

题目

image.png

思路:动态规划

  • maxDP[i]以第i个元素结尾的乘积最大子数组的乘积
  • minDP[i]以第i个元素结尾的乘积最小子数组的乘积
  • 由于存在负数,那么会导致最大的变最小的,最小的变最大的。因此还需要维护最小值
  • maxDP应该在nums[i], maxDP[i - 1] * nums[i], minDP[i - 1] * nums[i]中选最大的,minDP同理

代码

class Solution {
    public int maxProduct(int[] nums) {
        int length = nums.length;
        int[] maxDP = new int[length];
        int[] minDP = new int[length];
        maxDP[0] = nums[0];
        minDP[0] = nums[0];
        int max = maxDP[0];
        for (int i = 1; i < length; i++) {
            maxDP[i] = Math.max(nums[i], Math.max(maxDP[i - 1] * nums[i], minDP[i - 1] * nums[i]));
            minDP[i] = Math.min(nums[i], Math.min(minDP[i - 1] * nums[i], maxDP[i - 1] * nums[i]));
            max = Math.max(max, maxDP[i]);
        }
        return max;
    }
}
  • 空间优化
//空间优化,利用滚动数组
class Solution {
    public int maxProduct(int[] nums) {
        int length = nums.length;
        int maxDP = nums[0];
        int minDP = nums[0];
        int max = maxDP;
        for (int i = 1; i < length; i++) {
            int preMinDP = minDP, preMaxDP = maxDP;//上一轮的值
            maxDP = Math.max(nums[i], Math.max(preMaxDP * nums[i], preMinDP * nums[i]));
            minDP = Math.min(nums[i], Math.min(preMinDP * nums[i], preMaxDP * nums[i]));
            max = Math.max(max, maxDP);
        }
        return max;
    }
}