1. 程式人生 > 實用技巧 >leetcode53. Maximum Subarray(動態規劃)

leetcode53. Maximum Subarray(動態規劃)

https://leetcode.com/problems/maximum-subarray/

題意為求最最大子陣列之和

這是一道非常經典的動態規劃的題目,用到的思路我們在別的動態規劃題目中也很常用,以後我們稱為”區域性最優和全域性最優解法“。
基本思路是這樣的,在每一步,我們維護兩個變數,一個是全域性最優,就是到當前元素為止最優的解是,一個是區域性最優,就是必須包含當前元素的最優的解。接下來說說動態規劃的遞推式(這是動態規劃最重要的步驟,遞迴式出來了,基本上程式碼框架也就出來了)。假設我們已知第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)。
程式碼如下:

public int maxSubArray(int[] A) {
    if(A==null || A.length==0)
        return 0;
    int global = A[0];
    int local = A[0];
    for(int i=1;i<A.length;i++)
    {
        local = Math.max(A[i],local+A[i]);
        global = Math.max(local,global);
    }
    return global;
}

  

轉載自:https://blog.csdn.net/linhuanmars/article/details/21314059