最大子段和問題------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種情況:
①
最大子序和爲的最大子序和
②
最大子序和爲的最大子序和
③
最大子序和爲,其中,;令s1=(其中);s2=(其中);最大子序和爲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