輸入一個整型數組,數組裏有正數也有負數。數組中一個或連續的多個整數組成一個子數組。求全部子數組的和的最大值。要求時間複雜度爲O(n)。java
輸入:2, -3, 4, 5, -9面試
輸出:9數組
和最大的連續子數組是 {4, 5},結果就是9。code
咱們先假設和最大連續子數組是從第一個數開始的。初始化和爲0。第一步是加上數字2,此時和爲2。第二步加上數字-3,此時和爲-1。那麼問題來了,咱們到底要不要加上數字-3呢?分析過程以下:table
由上述分析可知,加上-3,此時累加的子數組和是-1;不加-3,此時累加的子數組和是-3。-1大於-3,爲了後續的累加和更大,因此選擇加上-3。class
接下來,第三步要不要加上數字4,咱們依據上面的決策流程繼續分析。當加上數字4,此時累加和爲4-1=3;不加上數字4,意味着當前連續子數組終結於數字4以前,此時的累加和初始化爲0,加上數字4後和等於4。顯而易見,4大於3,因此咱們選擇拋棄前面的累加和,由數字4繼續開始。遍歷
後續步驟省略,總結一番。當咱們遍歷數組時,對於每一個數字,要麼與前面的子數組累加,要麼做爲新子數組的起點,若是累加以後的子數組和小於(或等於)當前數字,咱們就選擇拋棄前面的累加和,將當前數字做爲新子數組的起點。整個過程能夠用表格總結以下:總結
步驟 | 操做 | 累加的子數組和 | 最大的子數組和 |
---|---|---|---|
1 | 加2 | 2 | 2 |
2 | 加-3 | -1 | 2 |
3 | 拋棄累加的和-1,加4 | 4 | 4 |
4 | 加5 | 9 | 9 |
5 | 加-9 | 0 | 9 |
根據題目要求,咱們只須要求出連續子數組的最大和,若是面試官還要求找到連續子數組的起點與終點下標,那麼最終的java代碼以下:static
public class Main { public static int child_sum(int[] arr) { if (arr == null || arr.length < 1) { return 0; } int left0 = 0; int left1 = 0; int right = 0; int max = arr[0]; int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; if (sum <= arr[i]) { //使用<=仍是<呢? sum = arr[i]; left0 = i; } if (sum > max) { max = sum; left1 = left0; right = i; } } System.out.println("left:" + left1 + " right:" + right + " max:" + max); return max; } public static void main(String[] args) { int[] arr1 = new int[]{2, -3, 4, 5, -9}; int[] arr2 = new int[]{2, -2, 4, 5, -9}; int[] arr3 = new int[]{-2, -3, -4, -5, -9}; child_sum(arr1); child_sum(arr2); child_sum(arr3); } }
打印輸出:tab
left:2 right:3 max:9 left:2 right:3 max:9 left:0 right:0 max:-2
在上面的代碼中使用小於等於或者使用小於有什麼區別呢?
假設數組爲{2, -2, 4, 5, -9},若是判斷條件是小於等於當前數字,那麼所得的最大連續子數組爲{4, 5}。若是判斷條件是小於當前數字,那麼所得的最大連續子數組爲{-2, 2, 4, 5}。若是對最大連續子數組的長度沒有明確要求,使用小於等於進行判斷便可。