循环数组,求和最大子数组
2015-04-15 22:01
246 查看
题目:
返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
如果数组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('\n'+"子数组和的最大值为: "+sum);
}
}
截图:
![](http://images.cnitblog.com/blog2015/721181/201504/152151076204864.png)
总结:
这次主要的收获在于
1、在与同学讨论的过程当中,把问题转化了,即注意环形数组本质,用长度为2N的线性数组来替代就可以了。
2、关于和最大字数组长度的问题,主要是考虑两个相同数组相接的地方是否被涵盖在了最大子数组之内,特别的,当长度为N的数组的最大子数组是它本身的时候,此时所求出来的“最大子数组”是不正确的,长度l=2N,这点是值得注意的。
返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
如果数组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('\n'+"子数组和的最大值为: "+sum);
}
}
截图:
![](http://images.cnitblog.com/blog2015/721181/201504/152151076204864.png)
总结:
这次主要的收获在于
1、在与同学讨论的过程当中,把问题转化了,即注意环形数组本质,用长度为2N的线性数组来替代就可以了。
2、关于和最大字数组长度的问题,主要是考虑两个相同数组相接的地方是否被涵盖在了最大子数组之内,特别的,当长度为N的数组的最大子数组是它本身的时候,此时所求出来的“最大子数组”是不正确的,长度l=2N,这点是值得注意的。
相关文章推荐
- 结对开发-- 循环一维数组求和最大的子数组
- 循环数组求最大子数组
- 结对开发Ⅵ——循环二维数组求和最大的子数组
- 循环一维数组求最大子数组
- 数组、求和最大的子数组
- 结对开发Ⅴ——循环一维数组求和最大的子数组
- 求数组最大子数组
- 51nod 1050 循环数组最大子段和
- 51nod 1050 循环数组最大子段和 !!!!巧妙
- 51nod-1050 循环数组最大子段和
- “数组最大值求和”结对情况
- 求二维整形数组的子数组的和最大的子数组
- 求和最大的子数组
- iOS小常识 数组求和、最大,最小、平均值
- 不使用循环使用递归得到数组的值得求和
- A.2.4-数组的定义,遍历,求和,平均值,求最大值
- 【51nod】1050 循环数组最大子段和
- 在给定的数组中寻找“和最大”的那个子数组
- 51Nod 1050 循环数组最大子段和(DP—最大子段和变形)
- php和js中数组中分别循环找出最大的数。