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

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


最后两个区间结果的最大值即为所求的最大连乘结果。
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相乘。
【LeetCode|LeetCode 热题 HOT 100 第四十九天 152. 乘积最大子数组 中等题 用python3求解】参考: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里累积的最大值,再找出两者最大值

    推荐阅读