1. 程式人生 > >Leetcode 152. 乘積最大子序列

Leetcode 152. 乘積最大子序列

給定一個整數陣列 nums ,找出一個序列中乘積最大的連續子序列(該序列至少包含一個數)。

示例 1:

輸入: [2,3,-2,4]
輸出: 6
解釋: 子陣列 [2,3] 有最大乘積 6。

示例 2:

輸入: [-2,0,-1]
輸出: 0
解釋: 結果不能為 2, 因為 [-2,-1] 不是子陣列。

 

這裡用動態規化的方法,即dp[i]為以i結尾乘積最大連續數值,注意,由於有負數的存在,需要同時記錄最大值與最小值,因為負數的最小值再與正數可能出現最大值,所以用dp[i][0]表示最大值,dp[i][1]表示最小值,考慮到特殊情況,每次求最大值和最小值都要與當前陣列nums[i]比較。實際上不需要記錄下所有dp[i],只需記錄當前的dp和上一個狀態的dp[i],所以用滾動陣列技巧

class Solution {
public:
    int maxProduct(vector<int>& nums) 
    {
        vector<vector<int>> dp(2, vector<int>(2, 0));
        dp[0][0]=nums[0];       // 正最大值
        dp[0][1]=nums[0];       // 最小值
        int n=nums.size();
        int res=nums[0];
        int x,y;
        for(int i=1;i<n;i++)
        {
            x=i%2;                // 滾動陣列
            y=(i-1)%2;            // 滾動陣列
           dp[x][0]=max(dp[y][0]*nums[i],dp[y][1]*nums[i]);
           dp[x][0]=max(dp[x][0],nums[i]);
           dp[x][1]=min(dp[y][1]*nums[i],dp[y][0]*nums[i]);
           dp[x][1]=min(dp[x][1],nums[i]);
           res=max(res,dp[x][0]);
        }
        
        return res;
    
        
    }
};