最大子序和(最大子段和)
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
1> 暴力求解
基本思路就是遍历一遍,用两个变量,一个记录最大的和,一个记录当前的和。
时间复杂度 O(n^3)
80 ms(代码1)
class Solution :
def maxSubArray ( self, nums: List[ int ] ) - > int :
tmp = nums[ 0 ]
max_ = tmp
n = len ( nums)
for i in range ( 1 , n) :
if tmp + nums[ i] > nums[ i] :
max_ = max ( max_, tmp+ nums[ i] )
tmp = tmp + nums[ i]
else :
max_ = max ( max_, tmp, tmp+ nums[ i] , nums[ i] )
tmp = nums[ i]
return max_
2> 分治法
分治法就是它的最大子序和不是在左半边,就是在右半边,或者是穿过中间,对于左右边的序列,情况也是一样,因此可以用递归处理。中间部分的则可以直接计算出来
时间复杂度是O(nlogn)。
188 ms(代码2)
class Solution :
def maxSubArray ( self, nums: List[ int ] ) - > int :
n = len ( nums)
if n == 1 :
return nums[ 0 ]
else :
max_left = self. maxSubArray( nums[ 0 : len ( nums) // 2 ] )
max_right = self. maxSubArray( nums[ len ( nums) // 2 : len ( nums) ] )
max_l = nums[ len ( nums) // 2 - 1 ]
tmp = 0
for i in range ( len ( nums) // 2 - 1 , - 1 , - 1 ) :
tmp += nums[ i]
max_l = max ( tmp, max_l)
max_r = nums[ len ( nums) // 2 ]
tmp = 0
for i in range ( len ( nums) // 2 , len ( nums) ) :
tmp += nums[ i]
max_r = max ( tmp, max_r)
return max ( max_right, max_left, max_l+ max_r)
2.>动态规划
思路:
最大连续子序列一定是以某个元素结尾的,那么我们就思考以nums中每个元素结尾的连续子序列其最大和是多少。status数组存以nums[i]结尾的子序列的最大和,那么当思考nums[i+1]结尾的子序列的最大和时,显然只要考虑两种情况:
(1)是与以nums[i]结尾的最大子序列结合?
(2)还是以自己nums[i+1]为子序列?
具体做法:声明两个变量,一个变量存最终结果,一个缓存对目前状态有增益的子序列之和。如果之前的缓存的子序列之和大于零,说明其是对之后状态有增益的,加上当前状态的值并更新缓存;反之则舍弃,只取当前状态的值更新至缓存。
92 ms(代码3)
class Solution :
def maxSubArray ( self, nums: List[ int ] ) - > int :
size = len ( nums)
if size == 0 :
return 0
dp = [ 0 for _ in range ( size) ]
dp[ 0 ] = nums[ 0 ]
for i in range ( 1 , size) :
if dp[ i - 1 ] >= 0 :
dp[ i] = dp[ i - 1 ] + nums[ i]
else :
dp[ i] = nums[ i]
return max ( dp)
76 ms(代码4)
class Solution :
def maxSubArray ( self, nums: List[ int ] ) - > int :
ans, sums = float ( '-inf' ) , 0
for i in range ( len ( nums) ) :
sums = sums + nums[ i] if sums > 0 else nums[ i]
ans = max ( sums, ans)
return ans