题目:
返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。
同时返回最大子数组的位置。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
思路:
1、
a、定义长度为n的一维数组,实际随机生成的时候生成长度为2n的数组,即n+1~2n是对1~n的重复
b、利用长度为n时的求法,求和最大的子数组,并记录子数组长度l
c、经过分析,只有两种情况l<n;或者l=2n;当l=2n时,和最大子数组即为长度为n的数组本身。
2、
利用循环队列实现,实现入队即数组初始化,(以后有时间来实现)
源代码:
import java.util.Random;
import java.util.Scanner;
public class zuidashuzu_xunhuan{
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
int array[]=new int[100];
int flag_qi=0;
int flag_zh=0;
int flag1=0;
int flag2=0;//分别记录子数列的起始和结束位置
int sum,sumtemp;//表示子数列的和
Random r=new Random();
System.out.print("请输入数组元素的个数: ");
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
System.out.println("--------------------------------" +
"------------------------------------------");
for(int i=0;i<a;i++){
array[i]=r.nextInt()%10;
array[a+i]=array[i];
}
System.out.print("产生的随机数序列为: ");
for(int i=0;i<a;i++){
System.out.print(array[i]+" ");
}
System.out.println("");
sum=array[0];
sumtemp=sum;
for(int i=0;i<2*a;i++){
if(sumtemp<=0){
sumtemp=0;
flag_qi=i+1;
flag_zh=i;
}
if(i+1!=flag_qi+a){
sumtemp+=array[i+1];
flag_zh++;
if(sumtemp>sum){
sum=sumtemp;
flag1=flag_qi;
flag2=flag_zh;
}
}
else
break;
}
System.out.print("子数组的组成元素为: ");
for(int i=flag1;i<=flag2;i++)
System.out.print(array[i]+" ");
System.out.println(' '+"子数组和的最大值为: "+sum);
}
}
截图:
总结:
这次主要的收获在于
1、在与同学讨论的过程当中,把问题转化了,即注意环形数组本质,用长度为2N的线性数组来替代就可以了。
2、关于和最大字数组长度的问题,主要是考虑两个相同数组相接的地方是否被涵盖在了最大子数组之内,特别的,当长度为N的数组的最大子数组是它本身的时候,此时所求出来的“最大子数组”是不正确的,长度l=2N,这点是值得注意的。