给定一个整数数组 nums
,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
解题思路
类似问题
Leetcode 53:最大子序和(最详细的解法!!!)
Leetcode 300:最长上升子序列(最详细的解法!!!)
我们直接使用第一个问题中的解法,很快就可得到下面的解。
class Solution:
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
self.result = nums[0]
self._maxProduct(nums, len(nums) - 1)
return self.result
def _maxProduct(self, nums, index):
if index == 0:
return nums[0]
pre = self._maxProduct(nums, index - 1)
cur = max(pre*nums[index], nums[index])
self.result = max(self.result, cur)
return cur
但是上面这种解法是不正确的,因为我们通过上面的这种解法很容易陷入局部最优解(loc_max
)。例如
-1 2 -2
通过上面的算法,只会得到2
,实际上最后的结果应该是4
。
我们要怎么知道全局最大值(glb_max
)呢?实际上通过上面的例子我们也能看出些端倪。我们需要维护一个最小值(loc_min
),因为如果最小值是一个负数的话,那么最小值乘上一个负数就变成了一个正数,它很能是一个glb_max
。那么我们的转移方程就很简单了
代码如下
class Solution:
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
loc_min, loc_max = [0]*nums_len, [0]*nums_len
loc_min[0] = loc_max[0] = glb_max = nums[0]
for i in range(1, nums_len):
loc_min[i] = min(loc_max[i-1]*nums[i], loc_min[i-1]*nums[i], nums[i])
loc_max[i] = max(loc_max[i-1]*nums[i], loc_min[i-1]*nums[i], nums[i])
glb_max = max(loc_max[i], glb_max)
return glb_max
上面的解法其实非常不错了,但是我们依然有更好的,我们可以将空间复杂度降到O(1)
。
class Solution:
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
loc_min, loc_max = [0]*2, [0]*2
loc_min[0] = loc_max[0] = glb_max = nums[0]
for i in range(1, nums_len):
loc_min[1] = min(loc_max[0]*nums[i], loc_min[0]*nums[i], nums[i])
loc_max[1] = max(loc_max[0]*nums[i], loc_min[0]*nums[i], nums[i])
loc_min[0], loc_max[0] = loc_min[1], loc_max[1]
glb_max = max(loc_max[1], glb_max)
return glb_max
一个非常hacker
的解法。
class Solution:
def maxProduct(self, A):
"""
:type nums: List[int]
:rtype: int
"""
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(A + B)
reference:
https://leetcode.com/problems/maximum-product-subarray/discuss/183483/Easy-and-Concise-Python
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!