輸入一個整形數組,數組裏有正數也有負數。數組中連續的一個或多個整數組成一個子數組,每一個子數組都有一個和。 求全部子數組的和的最大值,要求時間複雜度爲O(n)。java
例如輸入的數組爲1, -2, 3, 10, -4, 7, 2, -5,和最大的子數組爲3, 10, -4, 7, 2, 所以輸出爲該子數組的和18。面試
求一個數組的最大子數組和,我想最直觀最野蠻的辦法即是,三個for循環三層遍歷,求出數組中每個子數組的和,最終求出這些子數組的最大的一個值。 令currSum[i, …, j]爲數組A中第i個元素到第j個元素的和(其中0 <= i <= j < n),maxSum爲最終求到的最大連續子數組的和。算法
且當全是負數的狀況時,咱們能夠讓程序返回0,也能夠讓程序返回最大的那個負數,這裏,咱們讓程序返回最大的那個負數。編程
參考代碼以下:數組
/* * 求一個數組的最大子數組和,我想最直觀最野蠻的辦法即是,三個for循環三層遍歷, * 求出數組中每個子數組的和,最終求出這些子數組的最大的一個值。 * 令currSum[i, …, j]爲數組A中第i個元素到第j個元素的和(其中0 <= i <= j < n), * maxSum爲最終求到的最大連續子數組的和。 * 且當全是負數的狀況時,咱們能夠讓程序返回0,也能夠讓程序返回最大的那個負數,這裏,咱們讓程序返回最大的那個負數。 */ public static int solution1(int[] arr) { int maxSum = arr[0]; for(int i=0;i<arr.length;i++) { for(int j=i;j<arr.length;j++) { int currSum = 0; for(int k=i;k<j;k++) { currSum+=arr[k]; } maxSum = Math.max(maxSum, currSum); } } return maxSum; }
此方法的時間複雜度爲O(n^3)。spa
事實上,當咱們令currSum爲當前最大子數組的和,maxSum爲最後要返回的最大子數組的和,當咱們日後掃描時,code
即blog
currSum = max(a[j], currSum + a[j]) maxSum = max(maxSum, currSum)
舉個例子,當輸入數組是1, -2, 3, 10, -4, 7, 2, -5,那麼,currSum和maxSum相應的變化爲:io
參考代碼以下:for循環
/* * 解法二 * 事實上,當咱們令currSum爲當前最大子數組的和,maxSum爲最後要返回的最大子數組的和,當咱們日後掃描時, * 對第j+1個元素有兩種選擇:要麼放入前面找到的子數組,要麼作爲新子數組的第一個元素; * 若是currSum加上當前元素a[j]後不小於a[j],則令currSum加上a[j],不然currSum從新賦值,置爲下一個元素,即currSum = a[j]。 * 同時,當currSum > maxSum,則更新maxSum = currSum,不然保持原值,不更新。 * 即 * currSum = max(a[j], currSum + a[j]) * maxSum = max(maxSum, currSum) */ public static int solution2(int[] arr) { int maxSum = arr[0]; int currSum = 0; for(int i=1;i<arr.length;i++) { currSum = Math.max(arr[i], currSum + arr[i]); maxSum = Math.max(maxSum, currSum); } return maxSum; }