標籤:style blog http color io ar for div 問題
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.For example, given the array [−2,1,−3,4,−1,2,1,−5,4],the contiguous subarray [4,−1,2,1] has the largest sum = 6.
思想難度:99,操作難度:50。思想大於行動的一項有力證明。這是一道非常經典的動態規劃的題目,用到的思路我們在別的動態規劃題目中也很常用,以後我們稱為”局部最優和全域最優解法“。差不多的DP問題參見:Jump Game, Jump Game II
基本思路是這樣的,在每一步,我們維護兩個變數,一個是全域最優,就是到當前元素為止最優的解是,一個是局部最優,就是必須包含當前元素的最優的解。接下來說說動態規劃的遞推式(這是動態規劃最重要的步驟,遞迴式出來了,基本上代碼架構也就出來了)。假設我們已知第i步的global[i](全域最優)和local[i](局部最優),那麼第i+1步的運算式是:
local[i+1]=Math.max(A[i], local[i]+A[i]),就是局部最優是一定要包含當前元素,所以不然就是上一步的局部最優local[i]+當前元素A[i](因為local[i]一定包含第i個元素,所以不違反條件),但是如果local[i]是負的,那麼加上他就不如不需要的,所以不然就是直接用A[i];
global[i+1]=Math(local[i+1],global[i]),有了當前一步的局部最優,那麼全域最優就是當前的局部最優或者還是原來的全域最優(所有情況都會被涵蓋進來,因為最優的解如果不包含當前元素,那麼前面會被維護在全域最優裡面,如果包含當前元素,那麼就是這個局部最優)。
接下來我們分析一下複雜度,時間上只需要掃描一次數組,所以時間複雜度是O(n)。空間上我們可以看出運算式中只需要用到上一步local[i]和global[i]就可以得到下一步的結果,所以我們在實現中可以用一個變數來迭代這個結果,不需要是一個數組,也就是如程式中實現的那樣,所以空間複雜度是兩個變數(local和global),即O(2)=O(1)
1 public class Solution { 2 public int maxSubArray(int[] A) { 3 if (A.length == 0 || A == null) return 0; 4 int GlobalLarge = A[0]; 5 int CurrLarge = A[0]; 6 for (int i=1; i<A.length; i++) { 7 CurrLarge = Math.max(A[i], CurrLarge+A[i]); 8 GlobalLarge = Math.max(CurrLarge, GlobalLarge); 9 }10 return GlobalLarge;11 }12 }
Leetcode: Maximum Subarray