暴力窮舉法:
public class 最大子段和問題_暴力枚舉 {
public static int MaxSubSunm(int a[])
{
int res=0;
for(int i=0;i<a.length;i++)
{
int sum=0;
for(int j=i;j<a.length;j++)
{
sum+=a[j];
if(sum>res) res=sum;
}
}
return res;
}
public static void main(String[] args)
{
int a[]=new int[]{-1,2,4,7,6,-4,-7,5,-1};
System.out.println(MaxSubSunm(a));
}
}
分治:
/**
* mid=(left+right)/2
* 分成三部分:
* 1.a[left,mid]
* 2.a[mid+1,right]
* 3.a[i][j],left<=i<=mid,mid+1<=j<=right
*/
public class 最大子段和問題_分治 {
public static int MaxSubSum(int[] a,int left,int right)
{
int sum=0;
if(left==right) sum=a[left]>0?a[left]:0;
else{
int mid=(left+right)/2;
int leftsum=MaxSubSum(a,left,mid);
int rightsum=MaxSubSum(a,mid+1,right);
//接下來考慮橫跨mid兩邊的情況
int s1=0,lefts=0;
for(int i=mid;i>=left;i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
int s2=0,rights=0;
for(int j=mid+1;j<=right;j++)
{
rights+=a[j];
if(rights>s2) s2=rights;
}
sum=s1+s2;
}
return sum;
}
public static void main(String[] args)
{
int a[]=new int[]{-1,2,4,7,6,-4,-7,5,-1};
System.out.print(MaxSubSum(a,0,a.length-1));
}
}
動態規劃:
bj=max{bj-1+aj,aj},1<=j<=n
時間複雜O(n)。
/**
* bj=max{bj-1+aj,aj},1<=j<=n
*/
public class 最大子段和問題_動態規劃 {
public static int MaxSubSum(int a[])
{
int temp=0,sum=0;
for(int i=0;i<a.length;i++)
{
temp=Math.max(a[i],temp+a[i]);
if(temp>sum) sum=temp;
}
return sum;
}
public static void main(String[] args)
{
int a[]=new int[]{-1,2,4,7,6,-4,-7,5,-1};
System.out.print(MaxSubSum(a));
}
}