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
.
class Solution {
public:
int maxProduct(int A[], int n) {
if(n == 0) return 0;
if(n == 1) return A[0];
int curmax = A[0];
int curmin = A[0];
int ans = A[0];
for(int ii = 1; ii < n; ii ++) {
int temp = curmin * A[ii];
curmin = min(A[ii], min(temp, curmax * A[ii]));
curmax = max(A[ii], max(temp, curmax * A[ii]));
ans = max(ans, curmax);
}
return ans;
}
};
上面这段代码是从别人那里学过来的。本人用了一个非常笨的办法!
对于一个序列!我们如何找到它最大的连续的乘机为正的序列呢!
假设一个这样的序列: [1, 2, 3, 0, 4, 5, 6, -1, 2, 3, -3, 4, 5, -4].
在程序遍历这个数组的时候,它可能遇到的有正数,负数 和 零。显然,如果遇到零,相当于数组就断掉了,我们只要知道过去的最大值就好了。关于负数,这个时候我们想想最小值的可能性,为什么我们要找最小值呢,因为如果出现两个负数,那么最小值很可能转变为最大值的。在上面的程序中,我们用curmin记录最小值:
int temp = curmin * A[ii];
curmin = min(A[ii], min(temp, curmax * A[ii]));
在这里,如果当前值是零。我们要重新开始了,最小值就是零。如果不是零,那么它就是当前值,和过去的最小值以及最大值分别乘以当前值中最小的一个。显然,这里有好几种情况。
如果过去没有负数,或者偶数个负数,并且A[ii] 大于零,curmin就是A[ii];如果小于零,就是过去的最大值乘以现在的值。
如果过去有负数,并且是奇数个,并且A[ii]大于零,curmin就是curmin和当前值的乘积。如果小于零,就是过去的最大值乘以现在的值。
curmax = max(A[ii], max(temp, curmax * A[ii]));
重置当前的最大值,那就是当前值和过去最小值乘以当前值以及过去最大值乘以当前值中最大的一个。
所谓的curmin,可能就是当前值的前一个位置上的值,或者当前值往前包含了奇数个负数和最多的与这些负数相邻的正数的乘积。
所谓的curmax,可能是当前值的前一个位置上的值,或者当前值往前的包含零个或者偶数个负数和最多的和这些负数相邻的正数的乘积。