[LeetCode]152. 乘積最大子數組

題目

給你一個整數數組 nums ,請你找出數組中乘積最大的連續子數組(該子數組中至少包含一個數字),並返回該子數組所對應的乘積。

示例 1:

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

示例 2:

輸入: [-2,0,-1]
輸出: 0
解釋: 結果不能爲 2, 因爲 [-2,-1] 不是子數組。

解題思路

對於乘法,我們需要注意,負數乘以負數,會變成正數,所以解這題的時候我們需要維護兩個變量,當前的最大值,以及最小值,最小值可能爲負數,但下一步可能會再乘以一個負數,當前的最大值就變成最小值,而最小值則變成最大值了。

動態方程如下:

maxdp[i + 1] = max(maxdp[i] * nums[i + 1], nums[i + 1],mindp[i] * nums[i + 1])
mindp[i + 1] = min(mindp[i] * nums[i + 1], nums[i + 1],maxdp[i] * nums[i + 1])
dp[i + 1] = max(dp[i], maxdp[i + 1])

考慮優化空間。由於第 i 個狀態只和第 i−1 個狀態相關,根據「滾動數組」思想,我們可以只用兩個變量來維護 i−1 時刻的狀態,一個維護 maxdp,一個維護mindp。(這裏需要一個臨時變量temp存儲上一步的maxdp)

temp = maxdp 
maxdp = max(temp * nums[i], nums[i], mindp * nums[i]) 
mindp = min(mindp * nums[i], nums[i], temp * nums[i])
res = max(maxdp, res)

代碼

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        n = len(nums)
        if n==0:
            return 0
        if n==1:
            return nums[0]
        res = nums[0]
        maxdp = nums[0]
        mindp = nums[0]
        for i in range(1, n):
            temp = maxdp
            maxdp = max(temp*nums[i], nums[i], mindp*nums[i]) 
            mindp = min(mindp*nums[i], nums[i], temp*nums[i])
            res = max(maxdp, res)
        return res
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章