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

Leetcode 152. 乘積最大子序列(Python3)

152. 乘積最大子序列

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

示例 1:

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

示例 2:

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

 

接下來都是DP的題。

class Solution:
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:return 0
        dp = [[0,0] for _ in range(len(nums))]
        dp[0][0], dp[0][1] ,res = nums[0],nums[0],nums[0]
        for i in range(1,len(nums)):
            dp[i][0] = max(dp[i-1][0]*nums[i],dp[i-1][1]*nums[i],nums[i])
            dp[i][1] = min(dp[i-1][0]*nums[i],dp[i-1][1]*nums[i],nums[i])
            res = max(dp[i][0],res)
        return res

 

優化下空間複雜度:

class Solution:
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:return 0
        dp = [[0,0],[0,0]]
        dp[0][0], dp[0][1] ,res = nums[0],nums[0],nums[0]
        for i in range(1,len(nums)):
            x ,y = i % 2,(i - 1) % 2
            dp[x][0] = max(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])
            dp[x][1] = min(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])
            res = max(dp[x][0],res)
        return res

 

看到大佬寫法:

class Solution:
    def maxProduct(self, A):
        B = A[::-1]
        for i in range(1, len(A)):
            A[i] *= A[i - 1] or 1
            B[i] *= B[i - 1] or 1
        return max(max(A),max(B)) 

總結:

該題不能以一維來考慮,因為存在負數的關係,所以要同時記錄他的最大值和最小值,所以用二維來記錄。

首先,定義遞推的狀態:dp[i]表示到i為止的乘積子序列。dp[i][0]代表乘積最大,dp[i][1]代表乘積最小(負的最大)。

然後要考慮,i>=0和i<0的情況,這裡我們用max()和min()直接求出遞推關係。

最後要求得是乘積最大子序列,所以比較最後結果和到i為止的最大乘積子序列(dp[i][0])的最大值,就為乘積最大子序列的最大值。