乘积最大的子数组
描述
中等
给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
解题
如果该数组中有0,那么可以看做被0拆分后的子数组的最大乘积
如果该数组中没有0,就可以分为两种情况
-
负数为偶数个。负负得正,直接全部相乘得到最大值
-
负数为奇数个。
- 从第一个数开始乘,直到遇见第一个负数(不乘上该负数),得到一个值;然后将该负数后面的数全部乘起来,得到另一个值。比较得到其中的较大值
- 从第一个数开始乘,直到遇见最后一个负数(不乘上该负数),得到一个值;然后将该负数后面的数全部乘起来,得到另一个值。比较得到其中的较大值。当然,可以先将数组逆序,然后按照上一种方式进行计算,得到较大值
- 在两个较大值间得到一个最大值
先定义一个max_res
直接从左至右相乘,记录当前最大值temp
,然后temp
和max_res
比较得到一个最大值
然后从右至左在计算一次得到max_res
-
当负数为偶数个时,从左至右的最大值和从右至左的最大值时相同的
-
当负数为奇数个时,从左至右一直乘到最后一个负数是,当前的
temp
是正数,此时max_res
的值为temp
,当乘以最后一个负数后,之后的temp
始终为负数,假设最后一个负数右边的数乘起来大于max_res
也不再更新max_res
,所以需要从右至左再乘一遍- 比如说,有数据
[1, -2, 3, -4, 5, -6, 7]
,从左至右计算时,max_res = (1 x -2 x 3 x -4 x 5) = 120
,后面的7就舍弃了;从右至左计算时max_res = (7 x -6 x 5 x -4 x 3) = 2520
。 - 第一个数到第一个负数乘积为1,第一个负数后边所有的数乘积为2520
- 第一个数到最后一个负数乘积为120,第一个负数后边所有的数乘积为7
- 其中,1明显比120小,7明显比2520小,所以不需要再比较(乘的时候已经包含在里面了)
- 最后120和2520中取较大值2520
- 比如说,有数据
class Solution:
def maxProduct(self, nums: List[int]) -> int:
temp = 1
max_res = nums[0]
for n in nums:
temp *= n
max_res = max(max_res, temp)
if n == 0:
temp = 1
temp = 1
for n in nums[::-1]:
temp *= n
max_res = max(max_res, temp)
if n == 0:
temp = 1
return max_res