题目描述
给定一个整数数组nums(有正有负),求最大子数组乘积
思路
求最大子数组乘积问题是求最大子数组之和演变而来,不过比求和更复杂一些。一个数相加于0不变,相加于一个负数变小;一个数与0相乘变为0,一个数与负数相乘有可能变大有可能变小。那么假设maxval[i]是以nums[i]结尾的最大子数组乘积,minval是以nums[i]结尾的最小子数组乘积,那么此时的最大值和最小值产生于maxval[i-1]*nums[i]
,minval[i-1]*nums[i]
和nums[i]
这三个数之间。我们用maxval[i]记录最大子数组乘积,minval[i]记录最小子数组乘积,用maxval[i]更新最大值res
代码实现
class Solution:
def maxProduct(self, nums: 'List[int]') -> 'int':
## 暴力求解
# maxp=nums[0]
# for i in range(len(nums)):
# curp=1
# for j in range(i,len(nums)):
# curp*=nums[j]
# if curp>maxp:
# maxp=curp
# return maxp
# B=nums[::-1]
# for i in range(1,len(nums)):
# nums[i]*=nums[i-1] or 1
# B[i]*=B[i-1] or 1
# return max(nums+B)
# def swap(a,b):
# return b,a
# minval=maxval=res=nums[0]
# for val in nums[1:]:
# if val<0:
# minval,maxval=swap(minval,maxval)
# maxval=max(val,val*maxval)
# minval=min(val,val*minval)
# res=max(res,maxval)
# minval=maxval=[0]*len(nums) # 报错
minval=[0]*len(nums)
maxval=[0]*len(nums)
minval[0]=maxval[0]=res=nums[0]
for i in range(1,len(nums)):
maxval[i]=max(nums[i],nums[i]*maxval[i-1],nums[i]*minval[i-1])
minval[i]=min(nums[i],nums[i]*maxval[i-1],nums[i]*minval[i-1])
res=max(res,maxval[i])
return res
其他思路
- 当nums[i]<0的时候,交换最大值和最小值
class Solution:
def maxProduct(self, nums: 'List[int]') -> 'int':
def swap(a,b):
return b,a
minval=maxval=res=nums[0]
for val in nums[1:]:
if val<0:
minval,maxval=swap(minval,maxval)
maxval=max(val,val*maxval)
minval=min(val,val*minval)
res=max(res,maxval)
return res
- 在讨论区看到了一个天秀的代码
class Solution:
def maxProduct(self, nums: 'List[int]') -> 'int':
B=nums[::-1]
for i in range(1,len(nums)):
nums[i]*=nums[i-1] or 1
B[i]*=B[i-1] or 1
return max(nums+B)
nums[i-1] or 1
意思就是:if nums[i-1]!=0:return nums[i-1] else :return 1
- 暴力求解
class Solution:
def maxProduct(self, nums: 'List[int]') -> 'int':
# 暴力求解
maxp=nums[0]
for i in range(len(nums)):
curp=1
for j in range(i,len(nums)):
curp*=nums[j]
if curp>maxp:
maxp=curp
return maxp