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
.
Seen this question in a real interview before?
Yes
No
先确定dp状态,即:
在遍历过程中,不断更新以当前元素为终点的subarray的
乘积极大值
(下面简称
极大值
)和
最大值
。
然后确定状态转移方程:本质上无非就是要做出一个二选一:要么继续把当前遍历的元素算上,扩展当前的subarray,要么就重新开始一个subarray
若是像数学上那样分类讨论,每次分三种情况最大正值,最小负值,0,上一次与下一次一起就是9种情况十分繁琐,还没考虑有时候最大值为负,最小值为正,十分繁琐。
有时候做题目应该有一种大局观,从细节中解脱出来。这点类似于做物理题时,不一定非要用动力学原理弄清整个过程和每个细节,有时候用简单的从功和能的角度,只关注最终状态也可以顺利解题。这题里
需要维护的当前最大值和当前最小值,都是在dp_min[i-1] * A[i],dp_max[i] * A[i],和A[i]这三者里面取一即可
。有了这个只关乎最终状态,不关乎过程细节的结论,解题过程可以大大简化。
int maxProduct(int* nums, int numsSize) {
int max = nums[0];
int prevMin = nums[0], prevMax = nums[0];
int curMin, curMax;
int a,b,c;
for (int i = 1; i < numsSize; ++i) {
a=prevMax * nums[i];
b=prevMin * nums[i];
c=nums[i];
prevMin = a<b?(a<c?a:c):(b<c?b:c);//三目运算符快速取最值
prevMax = a>b?(a>c?a:c):(b>c?b:c);
if(prevMax>max) max=prevMax;
}
return max;
}