/**
* 求最大子段和的简单算法
* 时间复杂度O(n^3)
* @param a
* @return
*/
public static int maxSum_1(int[] a) {
int sum=0;
int n=a.length-1;
//i控制最大子段和的起始下标
for(int i=0;i<=n;i++) {
//j控制最大子段和的末尾下标
for(int j=i;j<=n;j++) {
int thissum=0;
//每次计算每一个子段之和
for(int k=i;k<=j;k++) {
thissum+=a[k];
}
//判断当前子段和是否比之前上一个子段和大
if(thissum>sum) {
sum=thissum; //满足条件则更新最大子段和
}
}
}
return sum;
}
/**
* 优化算法,时间复杂度O(n^2)
* Sn+1=a[n+1]+Sn;
* @param a
* @return
*/
public static int maxSum_2(int[] a) {
int sum=0;
int n=a.length-1;
for(int i=0;i<=n;i++) {
int thissum=0;
for(int j=i;j<=n;j++) {
thissum+=a[j];
if(thissum>sum) {
sum=thissum;
}
}
}
return sum;
}
/**
* 动态规划算法
* @param a
* @return
*/
public static int maxSum_3(int[] a) {
int sum=0;
int n=a.length,b=0;//b记录每次求和
for(int i=0;i<n;i++) {
//b>0时开始求和,否则求和元素向后移动
if(b>0) {
b+=a[i];
}else {
b=a[i];
}
//b>sum时,重新赋值给sum
if(b>sum) {
sum=b;
}
}
return sum;
}
/**
* 递归分治算法
* @param a
* @param left
* @param right
* @return
*/
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 center=(left+right)/2;
int leftsum=maxSubSum(a,left,center);//计算左半部最大子段和
int rightsum=maxSubSum(a,center+1,right);//计算右半部最大子段和
int s1=0,ls=0;
for(int i=center;i>=left;i--) {
ls+=a[i];
if(ls>s1) {
s1=ls;
}
}
int s2=0,rs=0;
for(int i=center+1;i<=right;i++) {
rs+=a[i];
if(rs>s2) {
s2=rs;
}
}
sum=s1+s2;
if(sum<leftsum) {
sum=leftsum;
}
if(sum<rightsum) {
sum=rightsum;
}
}
return sum;
}
计算数组的最大子段和
最新推荐文章于 2021-05-21 16:29:07 发布