Leetcode 152. 乘積最大子序列(Python3)
阿新 • • 發佈:2019-01-10
給定一個整數陣列 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])的最大值,就為乘積最大子序列的最大值。