152. 乘积最大子数组
动态规划:
java
class Solution {
public int maxProduct(int[] nums) {
//子问题:以nums[i]结尾的整数前面最大的乘积
//maxDp[i] 表示:以 nums[i] 结尾的连续子数组的最大乘积
//minDp[i] 表示:以 nums[i] 结尾的连续子数组的最小乘积
//可以优化为prevMax,prevMin,因为maxDp[i]只与前面的数有关
//不仅要整理最大乘积,也要整理最小乘积,因为存在负数翻身的情况
//状态方程: maxDp[i] = Math.max(nums[i],nums[i]*maxDp[i-1],nums[i]*minDp[i-1])
// minDp[i] = Math.min(nums[i],nums[i]*maxDp[i-1],nums[i]*minDp[i-1])
//max = Math.max(nums[i],Math.max(prevMax*nums[i],prevMin*nums[i]))
//min = Math.min(nums[i],Math.min(prevMin*nums[i],prevMin*nums[i]))
//从左到右
// int n = nums.length;
// int[] maxDp = new int[n];
// int[] minDp = new int[n];
// int ans = nums[0];
// //初始值
// maxDp[0] = nums[0];
// minDp[0] = nums[0];
// for(int i = 1;i<n;i++){
// //这里要有两次Math.max和Math,min
// maxDp[i] = Math.max(nums[i],Math.max(nums[i]*maxDp[i-1],nums[i]*minDp[i-1]));
// minDp[i] = Math.min(nums[i],Math.min(nums[i]*maxDp[i-1],nums[i]*minDp[i-1]));
// ans = Math.max(ans,maxDp[i]);
// }
// return ans;
int n = nums.length;
int ans = nums[0];
int max = nums[0];
int min = nums[0];
for(int i = 1;i<n;i++){
int prevMax = max;
int prevMin = min;
max = Math.max(nums[i],Math.max(prevMax*nums[i],prevMin*nums[i]));
min = Math.min(nums[i],Math.min(prevMax*nums[i],prevMin*nums[i]));
ans = Math.max(ans,max);
}
return ans;
}
}
时间复杂度:O(N)
空间复杂度:O(1)