前幾天在微信訂閱號「待字閨中」中看到的一篇文章《小技巧求一個數組中子數組的最大和》,提供下Java的實現,而且在對題目作下小修改,原本打算直接在微信裏直接回復,可是發現沒法回覆,而後整理出一篇簡短博客吧。java
來自《小技巧求一個數組中子數組的最大和》;算法
題目:數組
輸入一個整形數組,數組裏有正數也有負數。數組中連續的一個或多個整數組成一個子數組,每一個子數組都有一個和。求全部子數組的和的最大值。要求時間複雜度爲 O(n)。例如輸入的數組爲 1, -2, 3, 10, -4, 7, 2, -5,和最大的子數組爲 3, 10, -4,7, 2, 所以輸出爲該子數組的和 18。微信
解答:測試
【只有子數組「前半部分」的和爲正數時,子數組的求和纔有可能最大】,在這個trick條件下,只須要遍歷一次數組就能夠。算法是:當從頭開始遍歷的元素的求和爲正數時,繼續向後遍歷。當求和爲負數時,從新開始計算求和,子數組的開始重置爲下一個元素。spa
原文提供的是Python的實現,我這裏經過Java來實現:code
package subarraymaxsum; public class MaxSumOfSubArray { public int maxSum(int[] array) { if (array == null || array.length == 0) { throw new IllegalArgumentException("array is null or empty."); } int result = array[0], mark = 0; for (int i = 0; i < array.length; i++) { int element = array[i]; if (mark >= 0) { mark += element; } else { mark = element; } if (mark > result) { result = mark; } } return result; } public static void main(String[] args) { MaxSumOfSubArray maxSumOfSubArray = new MaxSumOfSubArray(); int maxSum = maxSumOfSubArray.maxSum(new int[]{1, -2, 3, 10, -4, 7, 2, -5}); System.out.println(maxSum); } }
輸出: 18element
其實雖然原題中指出數組裏有正數和負數,當時通過實踐和思考,這個算法一樣適用於全是正數,或者全是負數的狀況。當全爲正數時,最大的和天然就是全部元素的和,當全爲負數時,最大和天然就是其中最大的那個負數的值。經過此算法都能獲得相應的結果。get
測試代碼-全是負數:博客
public static void main(String[] args) { MaxSumOfSubArray maxSumOfSubArray = new MaxSumOfSubArray(); int maxSum = maxSumOfSubArray.maxSum(new int[]{-100, -3, -10, -1, -7, -2, -5}); System.out.println(maxSum); }
輸出 -1
測試代碼-全是正數:
public static void main(String[] args) { MaxSumOfSubArray maxSumOfSubArray = new MaxSumOfSubArray(); int maxSum = maxSumOfSubArray.maxSum(new int[]{100, 3, 10, 1, 7, 2, 5}); System.out.println(maxSum); }
輸出 128
該算法能夠適用於任何數值數組,和數組中數組的正負無關。