LeetCode T152.Maximum Product Array/乘积最大子数组——动态规划
在本题中,若我们从前往后遍历数组,那么此后满足要求的解的每一个状态都等于max{state[i-1]*nums[i], nums[i]},这就构成了一个状态转移的关系,但同时由于乘法负负得正的特殊性,因此我们除了记录正值的最大值,同时也需要记录负值的最小值,即有两组状态转移方程:
1. maxF[i]=max{maxF[i-1]*nums[i], minF[i-1]*nums[i], nums[i]};
2. minF[i]=min{maxF[i-1]*nums[i], minF[i-1]*nums[i], nums[i]};
之后,可以看到在所有的表达式中,我们只需要记录maxF[i-1], minF[i-1]即可,因此我们可以优化用临时变量替代state[i-1],即:
1. maxF=minF=ans=nums[0];
//开始循环
2. mx=maxF, mn=minF;
3. maxF=max{mx*nums[i], mn*nums[i], nums[i]};
4. minF=min{mx*nums[i], mn*nums[i], nums[i]};
5. ans=max{ans, maxF};
return ans
时间复杂度为O(n),空间复杂度为O(1);
我的题解大妈如下,leetcode上运行用时4ms,内存占用5.9MB
int max(int a,int b,int c){ if(a>b){ if(b>c) return a; else if(c>a) return c; else return a; } else{ if(a>c) return b; else if(c>b) return c; else return b; } } int min(int a,int b,int c){ if(a<b){ if(b<c) return a; else if(c<a) return c; else return a; } else{ if(a<c) return b; else if(c<b) return c; else return b; } } int maxProduct(int* nums, int numsSize){ int maxF=nums[0],minF=nums[0],ans=nums[0]; for(int i=1;i<numsSize;i++){ int mx=maxF, mn=minF; maxF=max(mx*nums[i],mn*nums[i],nums[i]); minF=min(mx*nums[i],mn*nums[i],nums[i]); ans=maxF>ans?maxF:ans; } return ans; }