給定\(N\)個整數的序列\({A_1,A_2,\dots,A_N}\),求函數\(f(i,j)=max\{0,\sum_{k=I}^jA_K\}\)的最大值。算法
序列中有多個子列,咱們須要從中找出子列和最大的子列。數組
/* c語言實現 */ int MaxSubseqSum1(int A[], int N) { int ThisSum, MaxSum = 0; int i, j, j; for(i=0; i<N; i++){ /* i是子列左端位置 */ for (j=i; j<N; j++){ /* i是子列右端位置 */ ThisSum = 0; /* ThisSum是從A[i]到A[j]的子列和 */ for(k=i; k<=j; k++) ThisSum += A[k]; if(ThisSum > MaxSum) /* 若是剛獲得的這個子列和更大 */ MaxSum = ThisSum; /* 則更新結果 */ } /* j循環結束 */ } /* i循環結束 */ return MaxSum; }
# python語言實現 def max_subseq_sum1(arr: list, n: int): max_sum = 0 for i in range(n): for j in range(i, n): this_sum = 0 for k in range(i, j): this_sum += arr[k] if this_sum > max_sum: max_sum = this_sum
時間複雜度:
\[ T(n) = O(N^3) \]
當咱們知道\(i-j\)的和以後,不必從頭開始加,對於k的循環是多餘的。函數
/* c語言實現 */ int MaxSubseqSum2(int A[], int N) { int ThisSum, MaxSum = 0; int i, j, j; for(i=0; i<N; i++){ /* i是子列左端位置 */ ThisSum = 0; /* ThisSum是從A[i]到A[j]的子列和 */ for (j=i; j<N; j++){ /* i是子列右端位置 */ ThisSum += A[k]; /* 對於相同的i,不一樣的j,只要在j-1次循環的基礎上累加1項便可 */ if(ThisSum > MaxSum) /* 若是剛獲得的這個子列和更大 */ MaxSum = ThisSum; /* 則更新結果 */ } /* j循環結束 */ } /* i循環結束 */ return MaxSum; }
# python語言實現 def max_subseq_sum2(arr: list, n: int): max_sum = 0 for i in range(n): this_sum = 0 for j in range(i, n): this_sum += arr[k] if this_sum > max_sum: max_sum = this_sum
時間複雜度:
\[ T(n) = O(N^2) \]
一個專業的程序猿,設計了一個\(O(N^2)\)的算法,應該本能的想到是否能把他改進爲\(O(Nlog_N)\)的算法。優化
先把數組從中間一分爲二,遞歸的解決左半部分的問題,獲得左邊的最大子列和;遞歸的解決右半部分的問題,獲得右邊的最大子列和;解決跨越中間的最大子列和,從三者中取出最大的子列和,即爲解。this
時間複雜度:
\[ \begin{align} T(n) & = 2T(N/2)+cN,\,\quad{T}(1)=O(1) \\ & = \text{注意$T(n)$和$T(N/2)$的轉換關係}\\ & = 2[2T(N/2^2)+cN/2]+cN \\ & = 2^kO(1)+ckN\quad\text{其中$N/2^k=1$,即$k=log_2N$} \\ & = O(NlogN) \end{align} \]spa
因爲連續子列和出現負數,日後加數字只會讓後面的數字愈來愈大,所以能夠提早讓子列和歸零。設計
「在線」的意思是指每輸入一個數據就進行即時處理,在任何一個地方停止輸入,算法都能正確給出當前的解。code
/* c語言實現 */ int MaxSubseqSum4(int A[], int N) { int ThisSum, MaxSum; int i; ThisSum = MaxSum = 0; for(i=0; i<N; i++){ ThisSum += A[i]; /* 向右累加 */ if(ThisSum > MaxSum) MaxSum = ThisSUm; /* 發現更大和則更新當前結果 */ else if(ThisSum < 0) /* 若是當前子列和爲負 */ ThisSum = 0; /* 則不可能使後面的部分和增大,拋棄之 */ } return MaxSum; }
# python語言實現 def max_subseq_sum4(arr: list, n: int): this_sum = max_sum = 0 for i in range(n): this_sum += arr[i] if this_sum > max_sum: max_sum = this_sum elif this_sum < 0: this_sum = 0
時間複雜度:
\[ T(N) = O(N) \]
因爲時間複雜度較快,因此對於其餘人理解是很困難的。blog