題目
給你一個整數數組 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