您的位置:首页 > 其它

算法(一):最大子序列和问题的多种求解(打印子序列)

2018-02-02 16:35 429 查看
原题:给定整数(可以为负数),A1,A2,A3,….,AN,求子序列最大的值

分析:假定-3,16,-2,12,-4,-1的序列,最大子序列为16,-2,12=26

第一种算法

public static int maxSubSumOne() {
int[] a= {-3,16,-2,12,-4,-1};//-3/-3,-16/-3,-16,-2/...
int maxSum=0,indexFirst=0,indexLast=0;
for(int i=0;i<a.length;i++) {//-3为序列开始到最后-1
for(int j=i;j<a.length;j++) {//i开始到最后-1
int thisMax=0;
for(int k=i;k<=j;k++) {
thisMax+=a[k];//子序列的和-3/13/11/...
}
if(maxSum<=thisMax) {
maxSum=thisMax;
indexFirst=i;indexLast=j;//记录最大子序的下标
}
}
}
//打印最大子序列
for(;indexFirst<=indexLast;indexFirst++) {
System.out.print(a[indexFirst]+" ");
}
return maxSum;
}


分析:三层嵌套,运行时间为O(N^3)

第二种算法

public static int maxSubSumOne() {
int[] a= {-3,16,-2,12,-4,-1;//-3/-3,-16/-3,-16,-2/...
int maxSum=0,indexFirst=0,indexLast=0;
for(int i=0;i<a.length;i++) {//-3为序列开始到最后-1
int thisMax=0;
for(int j=i;j<a.length;j++) {//i开始到最后-1
thisMax+=a[j];//子序列的和-3/13/11/...
if(maxSum<=thisMax) {
maxSum=thisMax;
indexFirst=i;indexLast=j;//记录最大子序的下标
}
}
}
//打印最大子序列
for(;indexFirst<=indexLast;indexFirst++) {
System.out.print(a[indexFirst]+" ");
}
return maxSum;
}


分析:二层嵌套,运行时间为O(N^2)

第三种算法

public static int maxSumThree(int[] a,int left,int right) {
if(left==right) {//递归基础:最后只有一个元素
return a[left];//最大子序
}
int center =(left+right)/2;
int maxLeftSum = maxSumThree(a,left,center);
int maxRightSum= maxSumThree(a,center+1,right);
int maxLeftBorderSum =0,leftBorderSum=0;
//左侧子序包含最后一个元素的最大子序列和
for(int i=center;i>=left;i--) {//center
leftBorderSum +=a[i];
if(leftBorderSum>maxLeftBorderSum) {
maxLeftBorderSum=leftBorderSum;
}
}
//右侧子序右半部分子序列中包含第一个元素的最大子序列和
int maxRightBorderSum =0,rightBorderSum=0;
for(int i=center+1;i>=left;i--) {//center+1
rightBorderSum +=a[i];
if(rightBorderSum>maxRightBorderSum) {
maxRightBorderSum=rightBorderSum;
}
}
//返回max3
int maxSum=maxLeftBorderSum+maxRightBorderSum;
if(maxSum<maxRightSum) {maxSum=maxRightSum;}
if(maxSum<maxLeftSum){maxSum=maxLeftSum;}
return maxSum;
}

public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a= {-3,16,-2,12,-4,-1};//-3,16,-2(center)12,-4,-1
System.out.print(maxSumThree(a,0,a.length-1));
}


分析:使用分治策略结合递归思想,时间复杂度为O(NlogN)。

第四种算法

public static int maxSumFour(int[] a) {
int maxSum=0,thisSum=0;
int index=0,indexFirst=0,indexLast=0;
for(int j=0;j<a.length;j++) {
thisSum +=a[j];
if(thisSum>maxSum) {
maxSum = thisSum;
if(index==1) {//记录打印子序列的下标
indexFirst=j;//开始下标
}else {
indexLast=j;//结束下标
}
}else if(thisSum<0) {//关键点:累加为负,即重新累加
thisSum=0;
}
}
//打印最大子序列
for(;indexFirst<=indexLast;indexFirst++) {
System.out.print(a[indexFirst]+" ");
}
return maxSum;
}


分析:算法也是解决问题,如此轻巧的解决,perfect。时间复杂度为O(N)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: