第一种思路:dp
假设我们考虑到第i个数,如果说这个数是正数,我们希望第i-1个数也是个正数,越大越好,如果说第i个数是个负数,我们希望第i-1个数也是个负数,并且越小越好。
所以应该同时维护两个dp数组,dp1[i]以i结尾的连续元素的最大值,dp2[i]表示以i结尾的连续元素的最小值。
转移方程
dp1[i]=max(dp1[i-1]*nums[i],dp2[i-1]*nums[i],nums[i]);
dp2[i]=min(dp2[i-1]*nums[i],dp1[i-1]*nums[i],nums[i]);
然后记录一下最大值就好了
code:
class Solution { public: int maxProduct(vector<int>& nums) { int n=nums.size(); vector<int >dp1(n+2,-1e9),dp2(n+2,-1e9); int ans=-1e9; dp1[0]=1; dp2[0]=1; for(int i=1;i<=n;i++){ dp1[i]=max(dp1[i-1]*nums[i-1],max(nums[i-1],dp2[i-1]*nums[i-1])); dp2[i]=min(dp2[i-1]*nums[i-1],min(nums[i-1],dp1[i-1]*nums[i-1])); ans=max(ans,dp1[i]); ans=max(ans,dp2[i]); } return ans; } };
第二种思路是我比较喜欢的思路,假设说数组里边没有0,如果说数组里负数的个数是偶数个,那答案直接就是全部元素相乘喽,如果说有奇数个负数,那么答案一定是以某一个负数分界线,然后取左边和右边的最大值。如果遇到了0怎么办,当遇到了0,我们可以把0这个位置视为一个新的起点。
code:
class Solution { public: int maxProduct(vector<int>& nums) { int n=nums.size(); int ans=-1e9; int t=1; for(int i=0;i<n;i++){ if(nums[i]==0) { ans=max(ans,0); t=1; } else{ t=t*nums[i]; ans=max(ans,t); } } t=1; for(int i=n-1;i>=0;i--){ if(nums[i]==0) { ans=max(ans,0); t=1; } else{ t=t*nums[i]; ans=max(ans,t); } } return ans; } };