子数组的最大乘积
【摘要】 子数组的最大乘积读前福利,送大家一些电子书LeetCode 152. 乘积最大子数组 问题描述给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。示例:输入:[2,3,-2,4]输出:6说明:子数组 [2,3] 有最大乘积 6。 分析问题这道题和求子数组的最大和很像,建议大家先去看53. 最大子序和。这里我们假设以第i...
子数组的最大乘积
读前福利,送大家一些电子书
问题描述
给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例:
输入:[2,3,-2,4]
输出:6
说明:子数组 [2,3] 有最大乘积 6。
分析问题
这道题和求子数组的最大和很像,建议大家先去看53. 最大子序和。这里我们假设以第i个数结尾的连续子数组的最大乘积为fmax(i),对于以第i个数结尾的子数组来说,因为nums[i]有可能是正数,也有可能是负数,需要分两种情况来讨论。
- 如果nums[i]为整数,那么fmax(i)要么等于nums[i],要么等于fmax(i-1) * nums[i],即fmax(i)=max(nums[i],fmax(i-1)+nums[i])。
- 如果nums[i]为负数,那么fmax(i)要么等于nums[i],要么等于以它前一个位置结尾的最小值和nums[i]的乘积,因为一个负数乘以一个最小值,它的结果反而大。这里我们假设以第i个数结尾的连续子数组的最小乘积为fmin(i),因此可以得出fmax(i)=max(nums[i], fmin(i-1) *nums[i])。
综上所述,对于以第i个数结尾的连续子数组来说,我们需要维护两个状态,即最大乘积fmax(i)和最小乘积fmin(i),且状态转移方程为:
fmax(i) = max {fmax(i-1) * nums[i] , nums[i] , fmin(i-1) * nums[i]}
fmin(i) = min {fmin(i-1) * nums[i], nums[i] , fmax * nums[i]}



下面我们来看一下代码的实现。
class Solution:
def maxProduct(self,nums):
n=len(nums)
dp_max=nums[:]
dp_min=nums[:]
for i in range(1,n):
dp_max[i]=max(nums[i],dp_min[i-1] * nums[i],dp_max[i-1] * nums[i])
dp_min[i]=min(nums[i],dp_min[i-1] * nums[i],dp_max[i-1] * nums[i])
return max(dp_max)
该算法的时间复杂度和空间复杂度都是O(n)。由于第i个状态只有i-1的状态有关,所以我们不需要保存i-1之前的状态,因为我们只需要常数个变量就可以求解,如下所示。
class Solution:
def maxProduct(self,nums):
n=len(nums)
dpmax=nums[0]
dpmin=nums[0]
res=nums[0]
for i in range(1,n):
tmpmax=dpmax
tmpmin=dpmin
dpmax=max(nums[i], tmpmin * nums[i], tmpmax * nums[i])
dpmin=min(nums[i], tmpmin * nums[i], tmpmax * nums[i])
res=max(dpmax,res)
return res
该算法的时间复杂度是O(n),空间复杂度是O(1)。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)