Maximum Product Subarray
- 问题描述:leetcode:152
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.给定一个数组,找出该数组的连续字串中乘积最大的值;比如给定 [2,3,-2,4],则答案时当为 [2,3]时,答案为6。
思路:
- 数组中的元素可以为正也可以为负。
- 设置两个数组,分别记录包括当前元素在内的字串所能构成的最大和最小值。
- 至于当前最大(包括当前元素),可能是之前最大乘以当前元素、也可能是前一个元素最小乘以当前元素、也可能是当前元素。
- 然后根据当前元素最大更新全局元素最大。
- 该问题是dp问题,也是dp问题中的局部最优和全局最优问题。
代码:
int maxProduct(vector<int>& nums) {
vector<int> maxproduct(nums.size(),0);
vector<int> minproduct(nums.size(),0);
maxproduct[0] = nums[0];
minproduct[0] = nums[0];
int maxans = nums[0];
for (int i=1; i<nums.size(); i++) {
maxproduct[i] = max(nums[i], max(nums[i]*maxproduct[i-1], nums[i]*minproduct[i-1]));
minproduct[i] = min(nums[i], min(nums[i]*minproduct[i-1], nums[i]*maxproduct[i-1]));
maxans = max(maxans, maxproduct[i]);
}
return maxans;
}
测试:
int main() {
int a[] = {2, 3, -2, 4};
vector<int> b(a, a+sizeof(a)/sizeof(int));
printf("%d\n", maxProduct(b));
return 0;
}
输出:6
算法注意点:
maxproduct是包含nums[i]时的局部最大值,maxans是全局最大值;算完maxproduct后一定别忘了更新全局最大值。
maxans = max(maxans, maxproduct[i]);
- 以上空间复杂度为O(n),所以可以用临时变量来算这样空间复杂度为O(n):
int maxProduct(int[] A) { if (A.length == 0) { return 0; } int maxherepre = A[0]; int minherepre = A[0]; int maxsofar = A[0]; int maxhere, minhere; for (int i = 1; i < A.length; i++) { maxhere = Math.max(Math.max(maxherepre * A[i], minherepre * A[i]), A[i]); minhere = Math.min(Math.min(maxherepre * A[i], minherepre * A[i]), A[i]); maxsofar = Math.max(maxhere, maxsofar); maxherepre = maxhere; minherepre = minhere; } return maxsofar; }