152. Maximum Product Subarray(乘积最大子序列)

本文介绍了解决寻找具有最大乘积的连续子数组问题的方法。通过动态规划的方式,结合正负数对乘积的影响,实现了高效的求解算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.

Example 1:

Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:

Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

1.递归
2.动态规划
DP两部曲:
1.定义DP[i]:从下标为0一直到i的product subarray max
2.DP方程:DP[i]=max()
DP[i+1]=DP[i]*a[i+1] 但是如果a[i+1]是负数,这个方程就是错误的,我们就应该选DP[i]的最小值

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        N = len(nums)
        f = [0] * N #最大值
        g = [0] * N #最小值
        f[0]=g[0]=res=nums[0]
        for i in range(1,N):
            f[i] = max(f[i-1]*nums[i],g[i-1]*nums[i],nums[i])
            g[i] = min(f[i-1]*nums[i],g[i-1]*nums[i],nums[i])
            res=max(res,f[i])
        return res

上面的方法使用了数组实现,我们注意到,每次更新只用到了前面的一个值,所以可以使用变量优化空间复杂度。

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums: return 0
        N = len(nums)
        f = g = res = nums[0]
        for i in range(1, N):
            pre_f, pre_g = f, g
            f = max(pre_f * nums[i], nums[i], pre_g * nums[i])
            g = min(pre_f * nums[i], nums[i], pre_g * nums[i])
            res = max(res, f)
        return res

在上面两个做法中,使用求三个数最大、最小的方式来更新状态,确实很暴力。事实上可以使用判断,直接知道怎么优化。当nums[i]为正的时候,那么正常更新。如果nums[i]<=0的时候,需要反向更新。

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums: return 0
        N = len(nums)
        f = g = res = nums[0]
        for i in range(1, N):
            if nums[i] > 0:
                f, g = max(f * nums[i], nums[i]), min(g * nums[i], nums[i])
            else:
                f, g = max(g * nums[i], nums[i]), min(f * nums[i], nums[i])
            res = max(res, f)
        return res

在上面的做法中可以看出来,两个更新公式里面f和g的位置是互换的,所以可以提前判断nums[i]的正负进行提前的互换。

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums: return 0
        N = len(nums)
        f = g = res = nums[0]
        for i in range(1, N):
            if nums[i] < 0:
                f, g = g, f
            f, g = max(f * nums[i], nums[i]), min(g * nums[i], nums[i])
            res = max(res, f)
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值