LeetCode 热题 HOT 100 第四十九天 152. 乘积最大子数组 中等题 用python3求解

题目地址

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

测试用例的答案是一个32-位整数。

子数组 是数组的连续子序列。

示例 1:
输入: nums = [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。

示例 2:
输入: nums = [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

提示:
1 <= nums.length <= 2 * 104
-10 <= nums[i] <= 10
nums 的任何前缀或后缀的乘积都保证是一个32-位整数

在这里插入图片描述
解题思路:根据符号的个数

大体上分为数组包括0和不包括0两种情况。
其中,包括0分为3种情况:全为正数、偶数个负数、奇数个负数。

1.不包括0的情况

(1)全为正数
直接所有结果相乘即可。

(2)偶数个负数
负负得正,这种情况也直接将结果相乘即可。

(3)奇数个负数
因为偶数个负数相乘的结果肯定是正数,再把它们附近的所有正数连在一起就构成了最大连乘的子区间。所以我们需要做的就是,排除掉第一个负数或者最后一个负数,使得数组是连续子数组是偶数个负数的情况。
做法:分别从正反方向计算数组的累积,取这两个方向的累积的最大值即可。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后两个区间结果的最大值即为所求的最大连乘结果。

2.包含0的情况

同上面一样,分别从左往右以及从右往左连乘,一旦遇到0,那么下一个数就为它本身,表示区间从0处断开

算法实现

新建一个nums的反顺序数组nums_reverse,然后连乘nums[i-1] or 1。
当nums[i-1] != 0时,或运算结果就是nums[i-1]。
当nums[i-1] == 0时,或运算结果就是1。
这样就实现了0后的第一个数字不与0相乘。

参考:https://leetcode.cn/problems/maximum-product-subarray/solution/python5xing-bu-tong-yu-hui-su-dpde-tricksjie-fa-by/

代码实现:

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        nums_reverse = nums[::-1]
        for i in range(1, len(nums)): # 累积
            nums[i] *= nums[i - 1] or 1 # 如果nums[i - 1]==0,则nums[i]=nums[i]*1;如果nums[i - 1]!=0,则nums[i]=nums[i]*[i - 1]
            nums_reverse[i] *= nums_reverse[i - 1] or 1
        return max(max(nums),max(nums_reverse))
        # nums[1]存储nums前2两个元素的乘积,nums[2]存储nums前3个元素的乘积
        # return语句,先选出nums里累积的最大值,以及nums_reverse里累积的最大值,再找出两者最大值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值