算法题解:连续子数组的最大和及其下标
題目
輸入一個整型數組,數組里有正數也有負數。數組中一個或連續的多個整數組成一個子數組。求所有子數組的和的最大值。要求時間復雜度為O(n)。
舉例
輸入:2, -3, 4, 5, -9
輸出:9
和最大的連續子數組是 {4, 5},結果就是9。
思路
我們先假設和最大連續子數組是從第一個數開始的。初始化和為0。第一步是加上數字2,此時和為2。第二步加上數字-3,此時和為-1。那么問題來了,我們到底要不要加上數字-3呢?分析過程如下:
由上述分析可知,加上-3,此時累加的子數組和是-1;不加-3,此時累加的子數組和是-3。-1大于-3,為了后續的累加和更大,所以選擇加上-3。
接下來,第三步要不要加上數字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代碼如下:
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);} }打印輸出:
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}。如果對最大連續子數組的長度沒有明確要求,使用小于等于進行判斷即可。
轉載于:https://www.cnblogs.com/yueshutong/p/11469200.html
總結
以上是生活随笔為你收集整理的算法题解:连续子数组的最大和及其下标的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人生建议
- 下一篇: maven编译的时候排除junit测试类