跟 最大子串行問題

2021-07-27 20:37:22 字數 1388 閱讀 3426

給定乙個無序陣列,求其所有子串行的和的最大值。

很容易想到的解決方法就是窮舉法,比較各個子串行的和,最終找到最大值。這種方法很直觀,很簡單,但會用到多次迴圈,時間複雜度高,它的思路如下。

既然是要求子串行的和的最大值,那我就找出所有子串行的和,乙個個比較就是了。假設有n個元素,那麼我就迴圈n次,暫稱之為1層迴圈,從0開始一直到n - 1(從第乙個元素數到最後乙個元素),我們用i來表示1層迴圈的當前迴圈index。1層迴圈的每一次迴圈都在裡面再套一層2層迴圈,2層迴圈從i開始到n - 1,我們用j來表示2層迴圈當前的index,2層迴圈的序號j每增加一次,就累加一次,之後與最大值進行比較交換 。**如下圖。

此演算法兩層迴圈,效率並不高,時間複雜度為o(n²)。為什麼我們會得到時間複雜度如此low的演算法呢?因為我們採用的是最為直觀的演算法,最容易想到的演算法,也是造成重複工作最多的方法,窮舉法。我們並沒有做深度思考,容易得到的東西往往不是那麼好的。下面就讓我們做一次深度分析。

[方法二]

既然方法一是沒有經過深度思考得到的可能是效率差的演算法,那麼我該怎麼做深度思考呢?回想一下數軸,從左到右逐漸增大,並以0為分界線,0的左側為負數,右側為正數。那麼問題來了,乙個數字max加上另乙個數字num,什麼情況下才會變大?那就是只有當num為大於0的數的時候,反之當num小於0的時候就會變小。那麼好,我們是不是可以這樣,先認定第1個數是最大的數計為max,同時也是當前暫存的大於0的子串行和cur_sum(為什麼我們要儲存乙個大於等於0的和,因為和一旦小於0,誰和它相加都會造成減小的效果,最大子串行一定不是和這個數相加得到的,就應該拋棄。拋棄了我們不怕,因為max中始終儲存著計算過的最大值,最大值丟不了),從第2個開始數,直到最後乙個。max加上每個數得到的cur_sum相比max都會有三種效果:變小了、不變、變大了。如果變大了,那最大值max就失效,更新max;如果變小了,那麼我們就需要判斷這個cur_sum是不是小於0了,如果小於了0,最大值一定不會是某個數和這個負數cur_sum之和,那麼計和就應該到此為止,最大的子串行要麼是之前找到的max,要麼就在當前index之後的序列的子串行之中。說的可能不太容易懂,多多回味回味就好啦!**如下圖。

經過一番腦力思考,我們通過 [如果變小了,那麼我們就需要判斷這個cur_sum是不是小於0了,如果小於了0,最大值一定不會是某個數和這個負數cur_sum之和,那麼計和就應該到此為止,最大的子串行要麼是之前找到的max,要麼就在當前index之後的序列的子串行之中] 的思想成功的避免了遍歷過的元素「回頭算」的情況,去除了多重迴圈,將時間複雜度降為了o(n)。

最大子串行問題

問題描述 輸入一組整數,求出這組數字子串行和中最大值。也就是只要求出最大子串行的和,不必求出最大的那個序列。例如 序列 2 11 4 13 5 2,則最大子串行和為20。複雜度為o n 2 的演算法 include include int maxsubseqsum const int a,int n...

最大子串行問題

現在我們將敘述兩個演算法來求解最大子串行和問題 include int maxsubsequencesum int a,int n int main printf max d maxsubsequencesum a,15 return0 int maxsubsequencesum int a 15 ...

最大子串行問題

題目 給定乙個整數列 可能有負數 求該整數列每個子串行的和的最大值,如果都為負數則結果為0 例如 對於輸入 2,11,4,13,5,2 答案為20 從11 到 13,即就是 11 4 13 20 粗略 如下 已測試通過 include using namespace std arr 目標陣列,len...