最大子串演算法

2021-06-29 11:24:46 字數 2024 閱讀 8375

最大子串問題是一類經典問題,即在一串整形陣列中選取和最大的子串

給出問題描述:

對於乙個包含負值的數字串array[1...n],要找到他的乙個子串array[i...j](0<=i<=j<=n),使得在array的所有子串中,array[i...j]的和最大。

針對本問題,可有三種方法,一種是暴利破解列舉演算法,所有子串種類共有n+(n-1)+(n-2)+.....+1=n(n+1)/2個演算法複雜度為o(n^2),然後找出最大的

要說明kadane演算法的正確性,需要兩個結論。首先,對於array[1...n],如果array[i...j]就是滿足和最大的子串,那麼對於任何k(i<=k<=j),我們有array[i...k]的和大於0。因為如果存在k使得array[i...k]的和小於0,那麼我們就有array[k+1...j]的和大於array[i...j],這與我們假設的array[i...j]就是array中和最大子串矛盾。

其次,我們可以將陣列從左到右分割為若干子串,使得除了最後乙個子串之外,其餘子串的各元素之和小於0,且對於所有子串array[i...j]和任意k(i<=karray[p...q],否array[j+1...n]>array[p...q],無論誰大,我們都可以找到比array[p...q]和更大的子串,這與我們的假設矛盾,所以滿足條件的array[p...q]不可能跨越兩個子串。對於跨越更多子串的情況,由於各子串的和均為負值,所以同樣可以證明存在和更大的非跨越子串的存在。對於單元素和最大的特例,該結論也適用。

根據上述結論,我們就得到了kadane演算法的執行流程,從頭到尾遍歷目標陣列,將陣列分割為滿足上述條件的子串,同時得到各子串的最大字首和,然後比較各子串的最大字首和,得到最終答案。我們以array=為例,來簡單說明一下演算法步驟。通過遍歷,可以將陣列分割為如下3個子串(-2),(1,-3),(4,-1,2,1,-5,4),這裡對於(-2)這樣的情況,單獨分為一組。各子串的最大字首和為-2,1,6,所以目標串的最大子串和為6。

相關題目

pat:1007maximum subsequence sum

原始碼:(使用kadane演算法實現版本,演算法時間複雜度為線性)

#include using namespace std;

int arrs[10001];

int kadane(const int array, size_t length, int& left, int& right)

} else

}return max;

}int main(void)

if(maxs==0)

int sums=kadane(arrs,n,left,right);

if(sums>=0)

cout原始碼版本2:(使用遞迴方法實現,演算法複雜度為nlog(n))

演算法題之 最大子串

題目 給定一字串只包含數字,請寫乙個演算法,找出該字串中的最長不重複子串 不重複是指子串中每一元素不同於子串中其他元素 如 120135435 最長不重複子串為 201354 方法一 輔助陣列,o n n private static string norepeatsubstring string ...

演算法複習 最大子串和

由於這個演算法比較簡單就不搬什麼講義了 核心點是如果a i 到a j 的和如果是最大子串和的話 那麼a i 到i至j中任意乙個a的和肯定是小於0的 證明很好證 int b 0 int sum 0 for int i 1 i n i 來一道例題就好了 世界盃結束了,義大利人連本帶利的收回了法國人6年前...

最大子串乘積

最大子串乘積 輸入n個數,求它的最大的連續子串乘積。例 輸入 1 2 3 7 0 2 3 輸出 實現 include int max subsegment int arr int len 最大子段乘積函式 else if arr j 0 else return max int main main p...