返回一个首尾相连的整数数组中最大子数组的和
一、题目:n返回一个整数数组中最大子数组的和。
二、要求:
(1)n输入一个整形数组,数组里有正数也有负数。
(2)n数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
(3)n如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。
(4)n同时返回最大子数组的位置。
(5)求所有子数组的和的最大值。要求时间复杂度为O(n)。
三、解题思路:
因为题目要求数组首尾相邻,允许输出A[i-1]...A[n-1],A[0]...A[j-1]之和最大,所以定义了一个n为数组,(1)从第二个整数开始到第n个整数依次向前移一位,原来第一位的整数放到最后一位,形成新的数组,(2)求新数组的最大子数组和,然后重复(1)直至循环n次,最后一个数组与初始数组相等。求最大子数组和的方法为:从第一个数(判断第一个数的正负,若负舍去,看下一个数,若正继续)开始把数组(没加一个数,都要对此数判断正负,若负,把之前的值当作最大值储存起来,再继续,若正,继续 )相加,每加一个数对和进行判断,如果小于零,抛弃当前值,如果大于零,下一个数与零比较,小于零时,先将最大值与之前的和比较,在让和加上这个数,如果大于零,直接让和加上这个数,再取最大值和和之间的最大值。(未完成时间复杂度为O(n)的要求)。
四、源代码:
public class test { public static void main(String[] args) { // TODO Auto-generated method stub int N=20; int n=-20; int m=20; int a[]=new int[N]; Input(a,N,n,m); //随机产生a[N] System.out.println("数组a[N]为:"); for(int i=0;i<N;i++) //输出数组a[N] { System.out.print(a[i]+" "); } System.out.println(); int H[]={a[0],0,0}; for(int i=1;i<=N;i++) //求最大子数组和 { array(a,N); Maxarray(H,3,a,N,i); } System.out.println("最大子数组为:"); if(H[1]>H[2]) { for(int i=H[1];i<N;i++) { System.out.print("a["+i+"] "); } for(int i=0;i<=H[2];i++) { System.out.print("a["+i+"] "); } } else if(H[1]==H[2]) { System.out.print("a["+H[1]+"] "); } else { for(int i=H[1];i<=H[2];i++) { System.out.print("a["+i+"] "); } } System.out.println(); System.out.println("最大子数组和为:"+H[0]); } static void Input(int a[],int N,int n,int m) //随机产生数组a[N] { for(int i=0;i<N;i++) { a[i]=(int)(n+Math.random()*(m-n+1)); } } static void array(int a[],int N) //把数组第一个数放到最后,重新排列数组 { int q=a[0]; for(int i=0;i<N-1;i++) { a[i]=a[i+1]; } a[N-1]=q; } static void Maxarray(int H[],int L,int a[],int N,int m) //对数组求最大子数组,并记录它的最大子数组和,和数组的起始位置 { int Max=a[0]; int A=a[0]; int b=0; int c=0; int d=0; for(int i=1;i<N;i++) { if(A<0) { A=a[i]; if(Max<A) { Max=A; b=i; c=i; d=b; } else { b=i; } } else { if(a[i]<0) { if(Max<A) { Max=A; c=i-1; d=b; } A=A+a[i]; } else { A=A+a[i]; if(Max<A) { Max=A; c=i; d=b; } } } } if(H[0]<=Max) { H[0]=Max; if((d+m)<N) { H[1]=d+m; } else { H[1]=d+m-N; } if((c+m)<N) { H[2]=c+m; } else { H[2]=c+m-N; } } } }
五、程序运行截图:
六、总结:
我负责编程,严雅芳负责测试。
此次编程最大的体会是:没有好的编程思路,拿道题不能尽快的想出解决办法,没有更好的解题思路,没有完成要求。对于自己的思路也不能很好的表达出来,不知道这可不可以在以后锻炼出来。还有感觉自己的程序比别人的复杂,代码行数太多。