题目:给出一组正负不确定的数据,计算其中最大的子列和。
package hello;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
String str=s.nextLine();
int max=0,besti=0,bestj=0;
String []s1=str.split(",");
int []num = new int[s1.length];
for(int i=0;i<num.length;i++) {
num[i]=Integer.parseInt(s1[i]);
}
**
## //简单算法两重for循环计算最大子列和。
**
for(int i=0;i<num.length;i++) {
int thissum=0;
for(int j=i;j<num.length;j++) {
thissum+=num[j];
if(thissum>max) {
max=thissum;
besti=i;bestj=j;
}
}
}
System.out.printf("i=%d,j=%d,max=%d\n",besti+1,bestj+1,max);
## //分治算法,记录最大子列段的起始位置会比较麻烦,这里采用数组进行传递数字。
int a[]=new int[8];
max=maxsubsum(num,0,num.length-1,a);
System.out.printf("i=%d,j=%d,max=%d\n",a[0]+1,a[1]+1,max);
## //贪心算法解决方式
max=greedy(num,0,num.length-1,a);
System.out.printf("i=%d,j=%d,max=%d\n",a[0]+1,a[1]+1,max);
}
public static int maxsubsum(int []num,int left, int right,int a[]) {
int max=0,thissum=0;
if(left==right) {
max=num[left]>0? num[left]:0;
a[5]=left;a[6]=right;
}
else {
int center=(left+right)/2;
int leftsum=maxsubsum(num,left,center,a); **//求得左边子列和**
int rightsum=maxsubsum(num,center+1,right,a); **//求得右边子列和**
**//以下求中间可能出现的最大子列和**
int lefts=0,s1=0;**//往左求可能出现的最大子列和,**
for(int i=center;i>=left;i--) {
lefts+=num[i];
if(lefts>s1) {
s1=lefts;
a[2]=i;
}
}
int rights=0,s2=0**;//往右求可能出现 的最大子列和**
for(int i=center+1;i<=right;i++) {
rights+=num[i];
if(rights>s2) {
s2=rights;
a[3]=i;
}
}
max=s1+s2;///**左右合并,并和左右子列和最大值比较,取三者中最大一个**
a[0]=a[2];a[1]=a[3];**//如果最大子列和出现在这里,那么他的起起始位置必然分别在center的左边和右边,前面已经记录**
if(leftsum>max) {
max=leftsum;a[0]=left;a[1]=center;**//最大子列出现在左边,则左边数组的始末位置就是子列和的石磨位置。
}**
if(rightsum>max) {
max=rightsum;
a[0]=center+1;a[1]=right;
}
}
return max;
}
public static int dynamic(int []num,int left, int right, int a[]) {
return right;
}
public static int greedy(int []num,int left, int right, int a[]) {
int thissum=0, max=0;
for(int i=0;i<num.length;i++) {
thissum+=num[i];
if(thissum<0) {
thissum=0; **//当前值小于,故而归零,重新开始,从下一个数开始计数**
a[0]=i+1;
}
if(thissum>max) {
max=thissum;a[1]=i; **// 当前值为最大值,记录当前足迹为最大子列和的最后位。**
}
}
return max;
}
}
结果:
-2,11,-4,13,-5,-2
i=2,j=4,max=20
i=2,j=4,max=20
i=2,j=4,max=20