给定一个整数数组 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])的最大值,就为乘积最大子序列的最大值。