子数组的最大乘积

举报
程序员学长 发表于 2022/02/16 18:39:40 2022/02/16
【摘要】 子数组的最大乘积读前福利,送大家一些电子书LeetCode 152. 乘积最大子数组 问题描述给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。示例:输入:[2,3,-2,4]输出:6说明:子数组 [2,3] 有最大乘积 6。 分析问题这道题和求子数组的最大和很像,建议大家先去看53. 最大子序和。这里我们假设以第i...

子数组的最大乘积

读前福利送大家一些电子书

LeetCode 152. 乘积最大子数组

问题描述

给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

示例:

输入:[2,3,-2,4]

输出:6

说明:子数组 [2,3] 有最大乘积 6。

分析问题

这道题和求子数组的最大和很像,建议大家先去看53. 最大子序和。这里我们假设以第i个数结尾的连续子数组的最大乘积为fmax(i),对于以第i个数结尾的子数组来说,因为nums[i]有可能是正数,也有可能是负数,需要分两种情况来讨论。

  1. 如果nums[i]为整数,那么fmax(i)要么等于nums[i],要么等于fmax(i-1) * nums[i],即fmax(i)=max(nums[i],fmax(i-1)+nums[i])。
  2. 如果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]}

image-20211103231024206

image-20211103231045825

image-20211103231107195

下面我们来看一下代码的实现。

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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。