1. 程式人生 > 實用技巧 >Leetcode 乘積最大子陣列 (兩種思路)

Leetcode 乘積最大子陣列 (兩種思路)

第一種思路: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;
    }
};