1.题目要求
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)
2.设计思路
(1)数组a中找子数组,求子数组和的最大值
先找到那些子数组,求出子数组的和,将子数组的和储存在另外一个数组b中保存,最后比较数组b中元素的大小,找出最大值。
在找子数组时用到了循环,从下标为0开始一直找到下标为n,当下标为i时,每次加上后面一个数据,并且和之前的数据比较,找到下标为i时的循环的最大值,记录在b中。依次循环找到其他的最大值存在b中,这样b中就只有n个数据了,不是总的子数组n*(n-1)个了。之后比较b中的数据,找到最大值就行了。
(2)将数组a首尾相连找子数组,求子数组和的最大值
要想找首尾相连的子数组和的最大值,其实只用找到首尾相连后的数组就行,举例就可以看出首尾相连之后的数组就是原数组的末尾加上除了最后一个数据之后的其他数据即可。之后的按照新的数组操作就行。
3.代码
import java.util.Scanner; public class Array { public static void main(String args[]) { Scanner s=new Scanner(System.in); System.out.println("请输入数组的个数:"); int n=s.nextInt(); int n1=2*n-1; int a[]=new int[n];//数组 int a1[]=new int[2*n-1]; int b[]=new int[n];//最大值 int max=0;//表示一个无穷小的数 //输入n个数 for(int i=0;i<n;i++) { System.out.print("请输入第"+ (i+1)+"个数:"); s=new Scanner(System.in); a[i]=s.nextInt(); } //首尾相连之后,就相当于在末尾加上除了最后一个数据的其他数据 System.out.print("首尾相连之后的数组结果是:"); for(int i=0;i<2*n-1;i++)//数组长度变为2*n-1 { if(i<n)a1[i]=a[i]; else a1[i]=a[i-n]; System.out.print(a1[i]+" "); } System.out.println(); for(int j=0;j<n;j++) {//求出每次循环的最大值,存在b中 //b的最大长度就是未首尾相连的长度。 b[j]=Max(b[j],a1,n1,j); } int ma=b[0];//初始值为数组的第一个值 for(int i=0;i<n;i++) { //Max(b[j],a,n,j) System.out.print("当i为"+i+"时,子数组的和的最大值是:"); System.out.println(b[i]+" "); if(ma<b[i])ma=b[i]; } System.out.println("最大值是:"+ma); } //判断最大值 b为最大值,a1是数组,n是数组中元素的个数,m是起始下标 public static int Max(int b,int a1[],int n,int m) { b=a1[m];int b1=a1[m]; for(int i=m;i<n;i++) { { if(i==m)b1=b1; else b1=b1+a1[i]; } if(b<b1)b=b1; } return b; } }
4.运行结果