目錄
(2)疑問一:當子序列之和爲非正數時,爲何不能繼續使用該序列?
(3)疑問二:當子序列之和爲非正數時,爲何不從子序列中的任一元素開始往後掃描,而是從子序列之後的元素開始掃描?
(1)先給出在線算法的僞代碼
僅針對至少含有一個正數的序列:
Solve_MaxSubSum(A, n):
sum <- 0
maxsum <- 0
boundleft <- 0
for i <- 0 to n-1 do
sum <- sum + A[i]
if sum <= 0 then
sum <- 0
boundleft <- i + 1
else if sum > maxsum then
maxsum <- sum
boundright <- i
maxsum = A[boundleft] + ... + A[boundright]
接下來,用以下序列舉例說明在線算法的詳細步驟
可以看出,在線算法僅掃描一遍序列即可求得最大子序列;其高效的本質在於當子序列和爲非正數時,該序列要被棄掉而要從序列之後的元素開始往後掃描。
(2)疑問一:當子序列之和爲非正數時,爲何不能繼續使用該序列?
此問題比較簡單,反證法即可證明。假設此序列爲seqone,且作爲序列seqtwo的頭部序列。
由於seqone是seqtwo的頭部序列,seqtwo刪除seqone後不影響剩餘元素的連續性;
再由於seqone的序列和爲非正數,seqtwo刪除seqone後序列和一定不會減小,甚至可能增大;
因此對於seqtwo來說,seqone沒有保留的必要。
(3)疑問二:當子序列之和爲非正數時,爲何不從子序列中的任一元素開始往後掃描,而是從子序列之後的元素開始掃描?
要回答這個問題,我們截取算法步驟中的一部分來說明,假設算法從A[i]開始往後掃描,直到遇到A[k],序列和才小於或等於0。
此時我們有以下條件:
條件(a):
條件(b):
接下來,我們不遵循在線算法的步驟(從序列之後的元素開始掃描),而是任取位於和之間的某一元素開始往後掃描,假設此元素是:
可以證明 以爲首端且末端不超過的任一序列之和,一定小於當前最大子序列和。
假設這段序列是,那麼一定成立,否則,違反了條件(b)。
因此,,證畢。
換句話解釋這個結論,即當子序列之和爲非正數時,沒有必要再從子序列中的任一元素開始往後掃描。