一、题目要求
1、输入一个整形数组,数组里有正数也有负数。
2、数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
3、求所有子数组的和的最大值。要求时间复杂度为O(n)
二、设计思想
解决方案一:
1、通过用户输入数组容量,随机产生一个整型数组
2、将数组元素依次相加进行判断,当遇到小于0的数时停止相加(因为要求最大子数组的和,加上小于0的数会让子数组和变小)
3、遍历相加的过程中不断更新子数组的和sum以及最大值max的值
4、遍历完成后输出max值即可
解决方案二:
1、通过用户输入数组容量,随机产生一个整型数组
2、通过循环遍历所有元素求出以该元素为首节点的所有子数组的和,将其存入一个list中
3、求出list的最大值
三、源代码
由于解决方案二的复杂度高于解决方案一,这里只给出解决方案一的代码
1 public static int getResult(ArrayList<Integer> array) { 2 int sum = 0; 3 int result = array.get(0); 4 for (Integer integer : array) { 5 if(sum<=0) 6 sum = integer; 7 else 8 sum += integer; 9 10 if(sum>result) 11 result = sum; 12 } 13 return result; 14 }
四、扩展
若将原数组首尾相连改为环状数组,求其最大子数组的和解决方案如下:
1、通过用户输入数组容量,随机产生一个整型数组
2、遍历数组中的所有元素,保证让其每个元素都作为一次首节点,将其前面的元素拼到原数组最后使其成为一个新数组
3、对每个新数组求一次最大子数组
4、将所有最大子数组的值比较大小,输出最大值
源代码如下:
import java.util.ArrayList; import java.util.Scanner; public class FirstTest { public static int getResult(ArrayList<Integer> array) { int sum = 0; int result = array.get(0); for (Integer integer : array) { if(sum<=0) sum = integer; else sum += integer; if(sum>result) result = sum; } return result; } public static void main(String[] args) { Scanner input=new Scanner(System.in); int num=input.nextInt(); int array[]=new int[num]; ArrayList<Integer> result = new ArrayList<>(); for(int i=0;i<num;i++) { if((int)(Math.random()*2)==0) { array[i]=(int)(Math.random()*10); } else { array[i]=-(int)(Math.random()*10); } } for(int i=0;i<num;i++) { System.out.println(array[i]); } for(int i=0;i<num;i++) { ArrayList<Integer> list = new ArrayList<>(); for(int j=i;j<num;j++) { list.add(array[j]); } for(int k=0;k<i;k++) { list.add(array[k]); } result.add(getResult(list)); } int max = result.get(0); for (Integer integer : result) { if(max<integer) max = integer; } System.out.println(max); } }
运行结果截图: