面试题42. 连续子数组的最大和
难度⭐
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
思路
贪心(选择使总和变大的)
-
如果 之前和 小于0 ,当前数字 与 之前和 的和 会更小,所以选
max(num,num+presum)
-
如果当前数字 小于0 同时 之前和大于0 ,会导致总和减小,所以需要记录总和
max(presum,maxsum)
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
#贪心
#如果当前和为负 会对总和造成负影响
#如果当前和为正 当前数字为负 可能造成总和减小 所以需要记录总和
if not nums:
return 0
presum,maxsum = float('-inf'),nums[0]
for num in nums:
presum = max(num,presum+num)
maxsum = max(maxsum,cursum)
return maxsum
动态规划
dp[i]
记录前i
个元素的最大和
- 如果
dp[i-1]<0
会使总和减小,dp[i]=nums[i]
- 如果
dp[i-1]>0
会使总和增加,dp[i]=nums[i]+dp[i-1]
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
#动态规划
if not nums:
return 0
dp = [float('-inf')]*len(nums)
dp[0] = nums[0]
for i in range(1,len(nums)):
dp[i] = nums[i]+dp[i-1] if dp[i-1]>0 else nums[i]
return max(dp)
152. 乘积最大子数组
难度⭐⭐
给你一个整数数组 nums
,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
思路
借鉴上一题最大子序和的思想,记录目前为止所有元素的最大乘积
- 但是在乘积会出现 负负得正 的情况,所以需要另外记录 最小乘积
- 判断 当前数字 的正负
- 如果为 负 ,
maxsum = max(num, minsum*num)
- 如果为 负 ,
coding
class Solution:
def maxProduct(self, nums: List[int]) -> int:
if not nums:
return 0
ans = float('-inf')
maxsum,minsum = 1,1
for num in nums:
if num < 0:
maxsum,minsum = minsum,maxsum
maxsum = max(num,maxsum*num)
minsum = min(num,minsum*num)
ans = max(ans,maxsum)
return ans