最大子串行

2022-05-04 13:48:09 字數 2003 閱讀 2733

一 問題描述:

輸入一組整數,求出這組數字子串行和中最大值。也就是只要求出最大子串行的和,不必求出最大的那個序列。例如:

序列:-3 18 -4 5 -5 -2,則最大子串行和為23。

二 解法1:窮舉解法

1

int maxsequence(int a,int

len)

9if(newsum >maxsum)

10 maxsum =newsum;

11} 12}

13return

maxsum;

14 }

這個演算法本身是非常簡單和容易理解的,通過三個for迴圈直接給出所有可能出現的子串行,從中選出乙個最大值即可。但是該方法時間複雜度真的是太大了,達到了o(n3)

有很多操作完成是重複性的操作。例如當i = 0時,j = 1 時:該演算法會計算a[0]+a[1],而當i = 0,j = 2時候,該演算法會計算a[0]+a[1]+a[2],顯然a[0]+a[1]被重複計算了。

三 解法2:窮舉解法2

1

int maxsequence2(int a,int

len) 10}

11return

maxsum;

12 }

這個演算法本身其實也是非常容易理解的,它不過是上面那個解法的改進,當我們計算i..j的值時候,i--j-1已經被計算過了,可以直接利用,不用重新計算一次i..j-1。其時間複雜度為o(n2),當然了,很明顯的,這個時間複雜度也還是非常高的,在計算機裡面,乙個演算法複雜度達到o(n2)其實還是一件比較可怕的事情。

四 解法3:分治法

int max3(int i, int j, int

k)int max_seq(int a,int left,int

right)

int rmax = a[mid+1

];

int rsum = 0

;for(int i = mid+1;i<=right;i++)

return max3(lmax+rmax,max_seq(a,left,mid),max_seq(a,mid+1

,right));

}int maxsequence3(int a,int

len)

這個演算法的核心就是分治思想。我們假設將我的已經知道的序列分成左右兩部分,那麼最大子串行存在的位置顯然有三種可能:

(1)  存在在序列的左部

(2)  存在在序列的右部

(3)  既存在在序列的左部又存在在序列的右部。

顯然如果是情況(3),是比較容易算出來的。如果是情況(1)和 (2)的話,我們可以將左部和右部當中乙個重新的序列計算,那麼新的序列又可以分成左右部分,重複以上即可。該演算法的時間複雜度了o(n * lg(n))。

五 解法四:動態規劃

int maxsequence4(int a,int

len)

return

maxsum;

}

該演算法的時間複雜度顯然就是o(n),對於計算機來說當然是非常友好的一件事情了,當是對於人來說就不是那麼友好了(當然了,神人除外)。

我們可以想一下,最大的子串行有什麼特點呢?那就是其前m個元素之和也一定不能小於0,為什麼?我們假設

序列a的長度為len,假設a[i].....a[j],表示為a的最大子串行。如果sum[i->i+m]< 0,那麼sum[i+m+1->j] > sum[i->j],矛盾。

**體現:

if(maxnew <= 0)

maxnew = a[i];

最大子串行

模板 int maxsubsequence const int a,int n return maxsum 複雜度on 給定k個整數的序列,其任意連續子串行可表示為,其中 1 i j k。最大連續子串行是所有連續子串行中元素和最大的乙個,例如給定序列,其最大連續子串行為,最大和 為20。在今年的資料...

最大子串行

最大子串行是要找出由數組成的一維陣列中和最大的連續子串行。比如的最大子串行就是 它的和是8,達到最大 而 的最大子串行是,它的和是6。你已經看出來了,找最大子串行的方法很簡單,只要前i項的和還沒有小於0那麼子串行就一直向後擴充套件,否則丟棄之前的子串行開始新的子串行,同時我們要記下各個子串行的和,最...

最大子串行

maxsum最大子串行問題。其實是動態規劃問題,遞推式如下 s 1 a 1 s n s n 1 0?s n 1 a n a n 注意點 暴力是可以解決問題,但是時間肯定會超時。暴力就是把所有子串行都查一遍然後找乙個最大的。如序列為123456,它的所有子串行為 1 2 3 4 5 6 12 123 ...