最大子段和問題------dp與分治法

最大子段和問題------dp與分治法

I.dp法

dm[i]表示以nums[i]爲右端點的最大子序和

class Solution {
    public int maxSubArray(int[] nums) {
        int max;
        int []dm=new int[nums.length];
        dm[0]=nums[0];
        max=dm[0];
        for(int i=1;i<nums.length;i++)
        {
            if(dm[i-1]<0)
            {
                dm[i]=nums[i];
            }
            else
            {
                dm[i]=dm[i-1]+nums[i];
            }
            if(max<dm[i])
                max=dm[i];
        }
        return max;
    }
}

時間複雜度o(n)

II.分治法

給定數組a[n],他的最大子序和分爲3種情況:

a0,a1.....an{a_{0},a_{1}.....a_{n}}最大子序和爲a0,a1.....an/2{a_{0},a_{1}.....a_{n/2}}的最大子序和

a0,a1.....an{a_{0},a_{1}.....a_{n}}最大子序和爲an/2+1,an/2+2.....an{a_{n/2+1},a_{n/2+2}.....a_{n}}的最大子序和

a0,a1.....an{a_{0},a_{1}.....a_{n}}最大子序和爲k=ijak{\sum_{k=i}^{j}a_{k}},其中1in/2{1\leqslant i \leqslant n/2},n/2jn{n/2 \leqslant j \leqslant n};令s1=max(k=in/2ak){max(\sum_{k=i}^{n/2}a_{k})}(其中1in/2{1\leqslant i \leqslant n/2});s2=max(k=n/2+1jak){max(\sum_{k=n/2+1}^{j}a_{k})}(其中n/2+1jn{n/2+1\leqslant j \leqslant n});a0,a1.....an{a_{0},a_{1}.....a_{n}}最大子序和爲s1+s2
代碼:

import org.junit.Test;
public class Test1 {
    //最大子段和問題
    @Test
    public void Test() {
        int array[]={-20,11,-4,13,-5,-2};
        System.out.println(MaxSum(array,0,array.length-1));
    }
    int MaxSum(int array[],int left,int right){
        if(left==right){
            return array[left];
        }else
        {
            int left_sum = MaxSum(array,left,(left+right)/2);//情況①
            int right_sum = MaxSum(array,(left+right)/2+1,right);//情況②
            int sum=0,s1=0,s2=0;
            int i;
            for(i=(left+right)/2;i>=left;i--){
                sum+=array[i];
                if(sum>s1)
                    s1=sum;
            }
            sum=0;
            int j;
            for(j=(left+right)/2+1;j<=right;j++){
                sum+=array[j];
                if(sum>s2)
                    s2=sum;
            }
            sum=s1+s2;
            //對比三種結果
            return java.lang.Math.max(java.lang.Math.max(sum,left_sum),right_sum);
        }
    }
}

輸出:20
T(n)=2*T(n/2)+n => T(n)=nlogn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章