還不會做最大子段和?

2022-09-08 23:18:20 字數 1952 閱讀 6134

最大子段和一定是每個(準)程式設計師都接觸過的問題,題目很簡潔:給出乙個長度為 n 的序列 a,選出其中連續且非空的一段使得這段和最大。為什麼每個(準)程式設計師都需要掌握呢?首先這問題解法很多,時間複雜度從o(n3) -> o(n2) -> o(nlog2n) -> o(n)。通過解決這個問題可以體會到不同演算法的效率差異,其次幾種解法中包含分治、字首和、貪心……等很多演算法思想,深入理解最大子段和問題可以舉一反三,對映到許多其他問題。

最容易想到的方法——列舉,然後就是**五分鐘,執行兩小時

int max = a[0]

;// 初始化最大值,不要寫 max = 0,因為最大子段和一定為正?

for(

int i =

0; i < n;

++i)

if(sum > max)

}}

int max = a[0]

;// 初始化最大值,不要寫 max = 0,因為最大子段和一定為正?

for(

int i =

0; i < n;

++i)

}}

int max = a[0]

;// 初始化最大值,不要寫 max = 0,因為最大子段和一定為正?

for(

int i =

0; i < n;

++i)

}}

上述演算法雖然優化了內部迴圈,但是時間複雜度任然不如人意,所以我們嘗試使用分治法來解決這個問題。

public

static

intf

(int

a,int x,

int y)

int mid = x+

(y-x)/2

;// 分治第一步,劃分子問題

int max1 =

math

.max(f

(a, x, mid),f

(a, mid, y));

// 分治第二步,遞迴求解子問題

// 分治第三步,合併子問題的解

int sum =0;

int max2 = a[mid-1]

;for

(int i = mid-

1; i >= x;

--i)

sum =0;

int max3 = a[mid]

;for

(int i = mid; i < y;

++i)

return

math

.max

(max1, max2+max3)

;// 三種情況中的最優解(最大和)

}

public

static

void

main

(string

args)

throws

ioexception

system

.out.

println

(max)

;// 輸出結果

in.close()

;}

import

j**a.io.*;

import

j**a.util.*;

public

class

main

public

static

void

main

(string

args)

throws

ioexception

system

.out.

println

(max);}

}

最大子段和

設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個...

最大子段和

再給頂的n個數的陣列中選出連續的若干個數,使得他們的和是最大的,即最大連續自序列和.列如.序列.1 2 3 1 6 5 9 結果 當取子串行 3,1,6,5,9 結果12 我的思路.1.最大連續子串行的開頭是在1.n之中.的最大連續和 2.求出以i,開頭的最大連續和,此時開頭已經確定了,那麼通過列舉...