题目
动态规划
public class Main {
public static void main(String[] args) {
Main main = new Main();
int [] nums = new int[] {2, 3, -2, 4};
main.maxProduct(nums);
}
public int maxProduct(int[] nums) {
if (nums.length == 1) {
return nums[0];
}
// 因为数组中存在负数, 所以当前位置i的最大连续子数组乘积的结果不能直接由dp[i - 1] * nums[i]得到
// 因此需要维护两个dp数组, 一个数组用来存储每个位置的最大连续乘积, 一个数组用来存储最小连续乘积
int [] dpMax = new int[nums.length];
int [] dpMin = new int[nums.length];
int max = Integer.MIN_VALUE;
for(int i = 0; i < nums.length; i ++) {
if (i == 0) {
dpMax[i] = nums[i];
dpMin[i] = nums[i];
} else {
dpMax[i] = Math.max(nums[i], Math.max(nums[i] * dpMax[i - 1], nums[i] * dpMin[i - 1]));
dpMin[i] = Math.min(nums[i], Math.min(nums[i] * dpMax[i - 1], nums[i] * dpMin[i - 1]));
}
max = Math.max(dpMax[i], max);
}
return max;
}
}
基本思路
-
首先数组只有整数, 不存在小数, 因此对于正数来说, 乘的越多越好.
-
数组中存在负数, 如果当前位置是负数的话, 那么之前存在的连续乘积中, 最小的那个和负数相乘才是最大的数字. 因此需要一个dpMin来维护每个位置的最小连续乘积
-
对于当前是正数的来说, 就需要维护一个dpMax来记录每个位置的最大连续乘积.
-
因此每个位置的最大值和最小值, 需要比较三个元素nums[i], dpMax[i - 1] * nums[i] 和dpMin[i - 1] * nums[i];