/*
f[i] = max(num[i], num[i] * num[i - 1], num[i] * num[i - 1] * num[i - 2],...)
= max(num[i], num[i] * f[i - 1]);
从这里看与“53. 最大子序和”非常类似。但是乘法存在负负为正。因此,当num[i] < 0, f[i] = max(num[i], num[i] * f[i - 1]);其中需要f[i - 1] 位置应该是最小的。因此,定义g[i] 作为最小值。
此时:
num[i] < 0; f[i] = max(num[i], num[i] * g[i - 1]);
num[i] > 0; f[i] = max(num[i], num[i] * f[i - 1]);
动态转移方程:f[i] = max(num[i], num[i] * g[i - 1], num[i] * f[i - 1]);
num[i] < 0; g[i] = min(num[i], num[i] * f[i - 1]);
num[i] > 0; g[i] = min(num[i], num[i] * g[i - 1]);
动态转移方程:g[i] = min(num[i], num[i] * g[i - 1], num[i] * g[i - 1]);
*/
class Solution {
public int maxProduct(int[] nums) {
int res = Integer.MIN_VALUE;
int n = nums.length;
int[] f = new int[n + 1];
int[] g = new int[n + 1];
f[0] = 1;
g[0] = 1;
for (int i = 1; i <= n; i ++) {
int a = nums[i - 1], fa = f[i - 1] * a, ga = g[i - 1] * a;
f[i] = Math.max(Math.max(fa, ga), a);
g[i] = Math.min(Math.min(fa, ga), a);
res = Math.max(res, f[i]);
}
return res;
}
}