最大子序列和

最大子序列和

給定(可能有負的)整數A1,A2,…,AN,求子序列和的最大值。
例如:對於輸入-2,11,-4,13,-5,-2,答案爲20(從A2到A4)

法1:窮舉所有的可能

時間複雜度爲

O(n^{3})
 public static int maxSubSum1(int a[]){
        int max=0;
        for (int i=0;i<a.length;i++){
            for (int j=i;j<a.length;j++){
                int s=0;
                for (int k=i;k<=j;k++){
                    s+=a[k];
                }
                if (s>max){
                    max=s;
                }
            }
        }
        return max;
    }
法2:撤銷一個for循環來避免三次的運行時間

時間複雜度爲

O(n^{2})
public static int maxSubSum2(int a[]){
        int max=0;
        for (int i=0;i<a.length;i++){
            int s=0;
            for (int j=i;j<a.length;j++){
                s+=a[j];
                if (s>max){
                    max=s;
                }
            }
        }
        return max;
    }
法3:使用分治法,先分別計算出左半部分、右半部分的最大子序列和,然後計算出跨越中間部分的最大子序列和,求三個中的最大值即可。

時間複雜度爲

O(nlogn)
//分治法
    public static int maxSubSum3(int a[],int left,int right){
        int max=0;
        if (left==right){
            if (a[left]>0)
                return a[left];
            else
                return 0;
        }
        int mid=(right+left)/2;
        int l=maxSubSum3(a,left,mid);//求左半部分的最大子序列和
        int r=maxSubSum3(a,mid+1,right);//求右半部分的最大子序列和
        /*求跨越中間元素的最大子序列和,
        左邊的從中間元素向左計算,右邊的從中間元素的下一個元素向右計算
        */
        int maxLeftBorderSum=0;
        int leftBorderSum=0;
        for (int i=mid;i>=left;i--){
            leftBorderSum += a[i];
            if (leftBorderSum>maxLeftBorderSum)
                maxLeftBorderSum=leftBorderSum;
        }
        int maxRightBorderSum=0;
        int rightBorderSum=0;
        for (int i=mid+1;i<=right;i++){
            rightBorderSum += a[i];
            if (rightBorderSum>maxRightBorderSum)
                maxRightBorderSum=rightBorderSum;
        }
        int max_lr=Math.max(l,r);
        max=Math.max(max_lr,maxLeftBorderSum+maxRightBorderSum);
        return max;


法4:動態規劃

令狀態dp[i]表示以A[i]作爲末尾的連續序列的最大值
當dp[i-1]>0,dp[i]=dp[i-1]+A[i]
否則,dp[i]=A[i]
所以,dp[i]=max(dp[i-1]+a[i],a[i]);

O(n)
//動態規劃
    public static int maxSubSum4(int a[]){
        int maxSum=0,thisSum=0;
        for (int i=0;i<a.length;i++){
            thisSum+=a[i];
            if (thisSum>maxSum)
                maxSum=thisSum;
            else if (thisSum<0)
                thisSum=0;
        }
        return maxSum;
    }

發佈了39 篇原創文章 · 獲贊 31 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章