最大子序和(最大子段和(python))

2021-09-28 19:51:16 字數 3057 閱讀 8145

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):

# 當前序列加上此時的元素的值大於tmp的值,說明最大序列和可能出現在後續序列中,記錄此時的最大值

if tmp + nums[i]

>nums[i]

: max_ =

max(max_, tmp+nums[i]

) tmp = tmp + nums[i]

else

:# 當tmp(當前和)小於下乙個元素時,當前最長序列到此為止。以該元素為起點繼續找最大子串行,並記錄此時的最大值

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 =

0for 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 =

0for 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'),

0for i in

range

(len

(nums)):

sums = sums + nums[i]

if sums >

0else nums[i]

ans =

max(sums, ans)

return ans

最大子段和 最大子矩陣和

給出n個整數序列 可能為負數 組成的序列a1,a2,an,求該序列形如 的子段和的最大值。當所有整數均為負數時,定義最大子段和為0。多測試用例。每個測試用例佔2行 第一行是序列的個數n 0 n 10000 第二行是n個整數。為每個測試用例輸出一行結果 最大子段和。6 2 11 4 13 5 2 31...

最大子段和

設a 是n個整數的序列,稱為該序列的子串行,其中1 i j n.子串行的元素之和稱為a的子段和.例如,a 2,11,4,13,5,2 那麼它的子段和是 長度為1的子段和 2,11,4,13,5,2 長度為2的子段和 9,7,9,8,7 長度為3的子段和 5,20,4,6 長度為4的子段和 18,15...

最大子段和

問題表述 n個數 可能是負數 組成的序列a1,a2,an.求該序列 例如 序列 2,11,4,13,5,2 最大子段和 11 4 13 20。1 窮舉演算法 o n3 o n2 2 分治法 將序列a 1 n 從n 2處截成兩段 a 1 n 2 a n 2 1 n 例項 三 最大子段和 問題表述 n個...