要求:
时间复杂度 O(n)
连续子数组要求和最大
从数组任意一个地方均可开始
参考来源:
http://www.cnblogs.com/waytofall/archive/2012/04/10/2439820.html
苦恼啊:
从网上和慧慧的程序中都发现了不完善之处,计算是轮了两圈之后的结果:
//慧慧基础上将数组改成 6 -3 -2 8 -4 验证。正确答案 为10 package test2; //从每一个正数位置开始,往后加若和为负数,则将上一个和放在链表,并进行下一个位置 import java.util.Scanner; public class Maxchoose { public static void main(String[] args) { // TODO Auto-generated method stub /* System.out.print("请输入数组的长度N="); Scanner scan=new Scanner(System.in); int length=scan.nextInt(); int arr[]=new int[length]; int arr2[]=new int[2*length-1];//首尾相连接时 for(int i=0;i<length;i++) { arr[i]=(int)(10-Math.random()*20); //产生-10到10的随机数 } */ int length=5; int arr[]={6,-3,-2,8,-4}; int arr2[]={6,-3,-2,8,-4,6,-3,-2,8}; System.out.print("数组:{ "); for(int i=0;i<length;i++) { System.out.print(arr[i]+" "); }//用于验证数组 System.out.println("}"); System.out.print("首尾相接数组:{ "); for(int m=0;m<2*length-1;m++) { if(m<length) { arr2[m]=arr[m]; } else { arr2[m]=arr[m-length]; } System.out.print(arr2[m]+" ");//用于验证首尾相接数组 } System.out.println("}"); int max=0; int curSum=0; int curIndex=0; int start=0; int end=0; for(int j=0;j<2*length-1;j++) { if(j==0) { max=arr2[j]; curSum=max; continue; } if(curSum<0) { curSum=0; curIndex=j; } curSum+=arr2[j]; if(curSum>max) { max=curSum; start=curIndex; end=j; } } System.out.print("子数组和最大为:{"); for(int i=start;i<=end;i++){ System.out.print(arr2[i]+" "); } System.out.print("} 值为"+max); } }//end
输出错误结果:
本应该是 {8 , -4 , 6}
发现此程序中的特点;
每一个最大字数组的开始和结束都是正数,如果开始元素加上后面的元素为正数就能继续加下去。
但是,我放弃,我投降,我缴械。
package test1; import java.util.Scanner; public class Test { static List vet=new List(); public static void main(String[] args) { int a1[]={8,-4,6,-3,-2}; int a2[]={6,-3,-2,8,-4,6,-3,-2,8}; //int a[]={-1,-2,-3,-4}; //测试全是负数的用例 int b[]=new int[a1.length]; for(int i=0;i<a1.length;i++) { b[i]=maxSum(a2,i,a1.length); } System.out.println("最大和为"+mm(b)); } public static int mm(int b[]) { int max=0; for(int i=0;i<b.length-2;i++) { if(b[i+1]>b[i]) max=b[i+1]; } return max; } public static int maxSum(int a[],int n,int m) { int sum=0; //其实要处理全是负数的情况,很简单,如稍后下面第3点所见,直接把这句改成:"int sum=a[0]"即可 //也可以不改,当全是负数的情况,直接返回0,也不见得不行。 int b=0; for(int i=n; i<n+m; i++) { if(b<0) //... b=a[i]; else b+=a[i]; if(sum<b) sum=b; } return sum; } }
结果:
本数组int a1[]={8,-4,6,-3,-2};
int a2[]={6,-3,-2,8,-4,6,-3,-2,8};
最大数组和 10
(6, -4 ,8)