今天在MOOC上的数据结构课中遇到了求解最大子列和问题,老师讲解了四种算法,并分析了四种算法的时间复杂度。本人通过几个小时的研究,终于写出四种算法的Java代码。特别是其中的分治算法和在线处理算法令人难以理解,需要好好研究学习。
算法一:穷举法
//求解最大子列和问题,穷举法(算法一)实现
public class thisMax {
public static void main(String[] agrs){
int[] A = {1,5,9,-5,50,-32,45,3,-55,-1,54,-48};
int sumMax = 0;
for(int i = 0;i < A.length;i++){//i是子列左端的位置
for(int j = i;j < A.length;j++){//j是子列右端的位置
int thisSum = 0;//thisSum是每个子列的和
for(int k = i;k <= j;k++)//k是计算每个子列的计数位
thisSum += A[k];
if(thisSum >sumMax)//判断新的子列和与之前得到的最大值
sumMax = thisSum;
}
}
System.out.println(sumMax);
}
}
算法二:穷举法(优化)
//求解最大子列和问题,穷举法(算法二)实现,只不过相对算法一做了优化
public class thisMax2 {
public static void main(String[] args) {
int[] A = {1,5,9,-5,50,-32,45,3,-55,-1,54,-48};
int sumMax = 0;
for(int i = 0;i < A.length;i++){//i是子列左端的位置
int thisSum = 0;//thisSum是每个子列的和
for(int j = i;j < A.length;j++){//j是子列右端的位置
thisSum += A[j];
if(thisSum >sumMax)//判断新的子列和与之前得到的最大值
sumMax = thisSum;
}
}
System.out.println(sumMax);
}
}
//求解最大子列和问题,分治法(算法三)实现
public class thisMax3 {
public static void main(String[] agrs){
int[] A = {1,5,9,-5,50,-32,45,3,-55,-1,54,-48};
thisMax3 t1 = new thisMax3();
System.out.println(t1.max(A, 0,A.length-1));
}
public int max(int A[],int left,int right){
thisMax3 t2 = new thisMax3();
if(left == right){//判断数组只有一组有效数据是的情况
if(A[0] > 0)
return A[left];
else
return 0;
}
int mid = (left+right)/2;//划分中界,左右段
int leftSum = t2.max(A, left, mid);
int rightSum = t2.max(A, mid+1, right);
int leftMax = 0,leftBorderSum = 0;
for(int i = mid;i >= left;i--){//左端最大子列和累加
leftBorderSum +=A[i];
if(leftBorderSum > leftMax)
leftMax = leftBorderSum;
}
int rightMax = 0,rightBorderSum = 0;
for(int j = mid+1;j <= right;j++){//右端最大子列和累加
rightBorderSum +=A[j];
if(rightBorderSum > rightMax)
rightMax = rightBorderSum;
}
return t2.max3(leftSum, rightSum, leftMax+rightMax);
}
public int max3(int a,int b,int c){//判断左右段和中间段为界的子列和大小
if(a>b)
b=a;
if(b>c)
return b;
else
return c;
}
}
算法四:在线处理
//求解最大子列和问题,在线处理法(算法四)实现
public class thisMax4 {
public static void main(String[] agrs){
int[] A = {1,5,9,-5,50,-32,45,3,-55,-1,54,-48};
int sumMax = 0,thisSum = 0;
for(int i = 0;i <A.length;i++){
thisSum += A[i];//向右累加
if(thisSum > sumMax)//判断当前子列和与已知最大子列和大小
sumMax = thisSum;
else{
if(thisSum < 0)//若当前子列和小于零,则必使后段子列和减小
thisSum = 0;//故抛弃之,取零
}
}
System.out.println(sumMax);
}
}