應用實例-最大子列和問題


一、最大子列和問題

給定\(N\)個整數的序列\({A_1,A_2,\dots,A_N}\),求函數\(f(i,j)=max\{0,\sum_{k=I}^jA_K\}\)的最大值。

序列中有多個子列,我們需要從中找出子列和最大的子列。

1.1 算法1-暴力破解

/* 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的循環是多余的。

1.2 算法2-適當優化

/* 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)\)的算法。

1.3 算法3-分而治之

先把數組從中間一分為二,遞歸的解決左半部分的問題,得到左邊的最大子列和;遞歸的解決右半部分的問題,得到右邊的最大子列和;解決跨越中間的最大子列和,從三者中取出最大的子列和,即為解。

時間復雜度:

\[\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} \]

1.4 算法4-在線處理

由於連續子列和出現負數,往后加數字只會讓后面的數字越來越大,因此可以提前讓子列和歸零。

“在線”的意思是指每輸入一個數據就進行即時處理,在任何一個地方中止輸入,算法都能正確給出當前的解。

/* 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) \]

由於時間復雜度較快,所以對於其他人理解是很困難的

二、算法運行時間比較


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM