演算法一:
演算法二:對這個問題,有乙個相對複雜的
o(nlogn)
的解法,就是使用遞迴。如果要是求出序列的位置的話,這將是最好的演算法了(因為我們後面還會有個
o(n)
的演算法,但是不能求出最大子串行的位置)。該方法我們採用「分治策略」(divide-and-conquer)。
在我們例子中,最大子串行可能在三個地方出現,或者在左半部,或者在右半部,或者跨越輸入資料的中部而佔據左右兩部分。前兩種情況遞迴求解,第三種情況的最大和可以通過求出前半部分最大和(包含前半部分最後乙個元素)以及後半部分最大和(包含後半部分的第乙個元素)相加而得到。
//遞迴法,複雜度是
o(nlogn)
long maxsumrec(const vector& a, int left, int right)
int center = (left + right) / 2;
long maxleftsum = maxsumrec(a, left, center);
long maxrightsum = maxsumrec(a, center+1, right);
//求出以左邊對後乙個數字結尾的序列最大值
long maxleftbordersum = 0, leftbordersum = 0;
for (int i = center; i >= left; i--) //
求出以右邊對後乙個數字結尾的序列最大值
long maxrightbordersum = 0, rightbordersum = 0;
for (int j = center+1; j <= right; j++)
return max3(maxleftsum, maxrightsum,
maxleftbordersum + maxrightbordersum);
} long maxsubsum3(const vector& a)
另外max3(long,long,long)
表示求三個
long
中的最大值:
//求出三個
long
中的最大值
long max3(long a, long b, long c)
if (a > c)
return a;
else
return c;
}對這個演算法進行分析:
t(1) = 1
t(n) = 2t(n/2) + o(n)
最後得出演算法的複雜度為:o(nlogn)
。
下面介紹乙個線性的演算法,這個演算法是許多聰明演算法的典型:執行時間是明顯的,但是正確性則很不明顯(不容易理解)。//線性的演算法
o(n)
long maxsubsum4(const vector& a)
return maxsum;
}很容易理解時間界o(n)
是正確的,但是要是弄明白為什麼正確就比較費力了。其實這個是演算法二的乙個改進。分析的時候也是
i代表當前序列的起點,
j代表當前序列的終點。如果我們不需要知道最佳子串行的位置,那麼
i就可以優化掉。
重點的乙個思想是:如果
a[i]
是負數那麼它不可能代表最有序列的起點,因為任何包含
a[i]
的作為起點的子串行都可以通過用
a[i+1]
作為起點來改進。類似的有,任何的負的子串行不可能是最優子串行的字首。例如說,迴圈中我們檢測到從
a[i]
到a[j]
的子串行是負數,那麼我們就可以推進i。
關鍵的結論是我們不僅可以把i推進到i+1,而且我們實際可以把它一直推進到j+1。
舉例來說,令p是
i+1到
j之間的任何乙個下標,由於前面假設了
a[i]+…+a[j]
是負數,則開始於下標
p的任意子序列都不會大於在下標
i並且包含從
a[i]
到a[p-1]
的子串行對應的子串行(
j是使得從下標
i開始成為負數的第乙個下標)。因此,把
i推進到
j+1是安全的,不會錯過最優解。
注意的是:雖然,如果有以
a[j]
結尾的某序列和是負數就表明了這個序列中的任何乙個數不可能是與
a[j]
後面的數形成的最大子串行的開頭,但是並不表明
a[j]
前面的某個序列就不是最大序列,
也就是說不能確定最大子串行在
a[j]前還是a[j]後,即最大子串行位置不能求出。但是能確保maxsum的值是當前最大的子串行和。
這個演算法還有乙個有點就是,它只對資料進行一次掃瞄,一旦
a[j]
被讀入處理就不需要再記憶。它是乙個聯機演算法
。
最大子序和
給定乙個整數陣列 nums 找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。示例 輸入 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。方法一 雙指標窮舉法 思路 要找到最大和的連續陣列,那麼就將所有可能的和都拿到,取到最大的即...
最大子序和
給定乙個整數陣列nums,找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。示例 輸入 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。高階 如果你已經實現複雜度為 o n 的解法,嘗試使用更為精妙的分治法求解。分析 1.暴力遍歷...
最大子序和
給定乙個整數陣列 nums 找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。示例 輸入 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。執行用時 104 ms,在所有 python3 提交中擊敗了26.24 的使用者 記憶體消耗...