求陣列的子陣列之和的最大值是在《程式設計之美》上的一道題,覺得挺有意思,就寫下此文,也便於自己以後溫習。
這道題的解法有很多種,比較容易想到的方法有列舉法,就是把所有的子陣列長度的和都計算一遍,求出其中的最大值。這種演算法的時間複雜度是o(n^2);還有分治法,就是將陣列分為一半一半,那麼最大和=max(左半邊的最大和,右半邊的最大和,左右兩邊銜接處所所構成的最大和),其解的示意圖如下所示。
這種解法的複雜度為o(nlogn)。當然,看過這本書的人,一定會知道其實還有一種更為簡便的方法。
這種解法只需要掃瞄一遍陣列,就可以得到答案。我們需要兩個輔助變數來完成這個過程:maxendhere和maxlen。其中maxendhere表示從掃瞄點開始相加所能獲得的最大和,而maxlen表示從陣列一端到掃瞄點處,所能獲得的最大連續和,這兩個變數的關係如下圖:
從這張圖可以看出,隨著陣列元素的掃瞄,maxendhere有可能轉化為maxlen(因為maxendhere也是連續子陣列之和,該值在掃瞄時可能大於之前計算得到的maxlen)。新的maxendhere=之前的maxendhere+array[i],i為掃瞄點,在得到新的maxendhere後,其值可能大於maxlen,從而成為新的maxlen。這樣,得到第一組關係式:
1)新的maxendhere=之前的maxendhere+array[i]
2)maxsum=新的maxendhere>maxsum ? 新的maxendhere:maxsum
另外,還有一種情況不能忽略,那就是當之前的maxendhere小於0時,根據上面的關係式,我們可以看到相加之後,新的maxendhere=之前maxendhere+array[i] < array[i],那麼此時應當有maxendhere=array[i],所以,還應當增加一組關係式:
3)新的maxendhere=新的maxendhere > array[i]? 新的maxendhere:array[i]
我們將上述兩組關係式綜合一下,得到新的關係式:
1)新的maxendhere=之前的maxendhere+array[i]
2)新的maxendhere=新的maxendhere > array[i]? 新的maxendhere:array[i]
3)maxsum=新的maxendhere>maxsum ? 新的maxendhere:maxsum
有了這三組關係式,就可以寫出程式了,很明顯,這種解法的時間複雜度是o(n)。
int get_max(int *a,int現在將其擴充套件為二維陣列,其問題變成求解子矩形中的最大和,如下圖所示:n)
return
maxsum;
}
我們希望能夠利用一維陣列的中o(n)的解法來幫助我們解決這個問題,那麼是否可行呢?
答案自然是可行的,我們需要做的是將二維陣列「合併」成一維陣列。如下圖將兩個相鄰的行陣列」合併「成乙個一維的陣列。
同理,可以合併n個相鄰的一維陣列,得到合併後的一維陣列。
得到一維陣列後,就可以使用一維陣列的求解方法,得到從start到end的範圍內所能得到的最大和。設二維陣列的大小是n(行) * m(列),那麼start的取值範圍為[0,n],而end的範圍為[start,n],列舉所有可行的(start,end)對,將這區間內的二維陣列合併為一維陣列,就可以求得該(start,end)取值對下的最大和。由此可寫出整個過程的**:
int get_max_2d(int **matrix,int n,int我們看到合併陣列和求解一維陣列的最大和的時間複雜度都是o(m),整個過程一共需要迴圈o(n^2)次,因此複雜度為o(m*n^2)。m) }
return
maxsum;
}
最大連續子陣列和
題目描述 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值,要求時間複雜度為o n 例如輸入的陣列為 1,2,3,10,4,7,2,5 和最大的子陣列為 3,10,4,7,2 因此輸出為該子陣列的和18。思路 採用貪婪法...
最大連續子陣列和
輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值,要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此輸出為該子陣列的和18。第乙個想法肯定就是如果能夠把陣...
最大連續子陣列和
給定乙個整數陣列,元素的值有正有負。定義 連續子陣列和 為連續幾個陣列的元素的和,求最大的連續子陣列和。已知這個值在int能夠表示的範圍內。無腦暴力做就是列舉所有的子陣列,o n 2 然後對於每個子陣列求和,自然就找出最大的了,複雜度總共是o n 3 能否優化?想想 做了重複多餘的事情了?沒錯,就是...