题目描述:
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
提示:
1 <= arr.length <= 10^5
-100 <= arr[i] <= 100
最大和连续子数组一定有如下几个特点:
- 第一个不为负数
- 如果前面数的累加值加上当前数后的值会比当前数小,说明累计值对整体和是有害的;如果前面数的累加值加上当前数后的值比当前数大或者等于,则说明累计值对整体和是有益的。
解题步骤:
-
定义两个变量,一个用来存储之前的累加值,一个用来存储当前的最大和。遍历数组中的每个元素,假设遍历到第 i i i个数时:
- 如果前面的累加值为负数或者等于0,那对累加值清0重新累加,把当前的第 i i i个数的值赋给累加值。
- 如果前面的累加值为整数,那么继续累加,即之前的累加值加上当前第 i i i个数的值作为新的累加值。
-
判断累加值是否大于最大和:如果大于最大和,则更新最大和;否则,继续保留之前的最大和。
AC代码
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
sum = nums[0]
presum = 0
for i in nums:
if presum < 0:
presum = i
else:
presum += i
sum = max(presum,sum)
return sum
上面的解题思想可以归纳到动态规划的思路中,创建dp数组,其中 d p [ i dp[i dp[i]表示 n u m s [ i ] nums[i] nums[i]为结尾的连续子数组的最大和,并设置 d p [ 0 ] = n u m s [ 0 ] dp[0] = nums[0] dp[0]=nums[0]:
- 如果nums[i] <=0,那么 d p [ i − 1 ] dp[i-1] dp[i−1]对 d p [ i ] dp[i] dp[i]没有贡献,设置 d p [ i ] = n u m s [ i ] dp[i] = nums[i] dp[i]=nums[i]
- 否则, d p [ i ] = n u m s [ i ] + d p [ i − 1 ] dp[i] = nums[i] + dp[i - 1] dp[i]=nums[i]+dp[i−1]
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
dp = [0 for i in range(len(nums))]
dp[0] = nums[0]
for i in range(1, len(nums)):
if dp[i - 1] > 0:
dp[i] = dp[i -1] + nums[i]
else:
dp[i] = nums[i]
return max(dp)