一、题目要求:
输入一个一维整形数组,数组里有正数也有负数。
一维数组首尾相接,像个一条首尾相接带子一样。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。
发表一篇博客文章讲述设计思想,出现的问题,可能的解决方案(多选)、源代码、结果截图、总结。
二、程序设计思想
1)一维数组定义和赋值。
2)计算子数组的和并比较
3)如果没有限制时间复杂度,我们很容易想到一种很简单的方法,就是用双重循环来实现,但是当时间复杂度限制为O(n)时,就该转换思路了。
三、出现的问题
(1) 在敲代码的时候突然想到,for循环下用if条件让max与数组数为1,2,……n的子数组进行比较,可是n是不确定的,所以子数组求和扔存在问题。
一直在思考,能不能边比较边求和,子数组的和用一个变量来存储,最大值用另一个变量来存储,收尾相接需要注意子数组的和,不控制可能会超过
最大是数组数。
(2)子数组和的数目可能会超过原来数组和的数目,用变量jishu来控制,k记录是第几次超过。如果超过了,maxstart置为0,jishu置为0,循环从k+1开始。
(3)如果都是负数,maxstart赋值为0时就会大于数组本身。我们把这种情况单独考虑,先判断是否全为负数,如果全为负数,单个元素的最大值即为
这个数组子数组和的最大值。
五、源代码
import java.util.Scanner;
public class maxArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
int i=0,maxsum=0;
boolean flag=true;
Scanner in=new Scanner(System.in);
System.out.println("请输入数组的大小:");
int number=in.nextInt();
int array[]=new int[number*2-1];
System.out.println("请输入数组的值:");
for(i=0;i<number;i++)
{
array[i]=in.nextInt();
if(i<number-1)
{
array[i+number]=array[i];
}
}
flag=Pan(array);
if(flag==true)
{
maxsum=Max(array);
}
else
{
maxsum=sumMax(array,number);
}
System.out.println("数组:");
for(i=0;i<array.length;i++)
{
System.out.print(array[i]+" ");
}
System.out.println("最大子数组的和为:"+maxsum);
in.close();
}
//-----最大子数组的和
public static int sumMax(int[] array,int number)
{
int i,jishu=0,k=0;//jishu 控制子数组个数,k记录第几次到达最大数组数
int maxstart=0;//子数组和的初始值
int maxsum=array[0];//初始值
for(i=0;i<array.length;i++){
maxstart+=array[i];
jishu++;
if((maxstart<0)){
{
maxstart=0;
jishu=0;
}
}
if(jishu>number)
{
if(k<number)
{
jishu=0;
i=k;//经过k++从下一轮开始
maxstart=0;
k++;
}
}
if(maxstart>maxsum){
maxsum=maxstart;
}
}
return maxsum;
}
//----判断数组是否全为负数,true 正数,false 负数
public static boolean Pan(int[] array)
{
boolean flag=true;
for(int i=0;i<array.length;i++)
{
if(array[i]>0)
{
flag=false;
}
}
return flag;
}
//------单个最大值
public static int Max(int[] array)
{
int max=array[0];
for(int i=0;i<array.length;i++)
{
if(array[i]>max)
{
max=array[i];
}
}
return max;
}
}
六、结果截图
全为负数的情况:



正负都有的情况:
