【算法导论】最大子数组问题
参考
1.暴力算法 O(n^2)
def maximum_subarray_1(nums):
siz=len(nums)
res=0
for i in range(siz):
sum=0
for j in range(i,siz):
sum+=nums[j]
if sum>res:
res=sum
return res
2.分治算法 O(n*logn)
思路:[le,ri)范围的最大子数组问题可分为中间点mi左边和中间点右边的子问题,以及跨越中间点的问题。前两个递归就行,最后一个从中间点开始往左右分别寻找最大子数组,加起来即为所求解。
def func(nums,le,ri):
#[le,ri)
if le>=ri:
return 0
mi=le+(ri-le)//2
res1=func(nums,le,mi)
res2=func(nums,mi+1,ri)
le_max=0
sum=0
for i in range(mi-1,-1,-1):
sum+=nums[i]
if sum>le_max:
le_max=sum
sum=0
ri_max=0
for i in range(mi+1,ri):
sum+=nums[i]
if sum>ri_max:
ri_max=sum
return max(max((res1,res2)),le_max+nums[mi]+ri_max)
def maximum_subarray_2(nums):
return func(nums,0,len(nums))
3.动态规划算法
def maximum_subarray_3(nums):
siz=len(nums)
if not siz:
return 0
dp=[0 for i in range(siz)]
dp[0]=nums[0]
for i in range(1,siz):
dp[i]=max(dp[i-1]+nums[i],nums[i])
return max(dp)
4.Kadane算法
def maximum_subarray_4(nums):
res=0
cur_sum=0
siz=len(nums)
if not siz:
return 0
for i in range(siz):
cur_sum+=nums[i]
if cur_sum<0:
cur_sum=0
if cur_sum>res:
res=cur_sum
return res
进击的小🐴农