题目:输入一个数组,数组中有正也有负,数组中连续的一个或者连续的多个数字组成一个子数组。求所有的子数组和的最大值。要求时间复杂度为O(n)
思路:我们的最直观的想法就是求出这个数组中的所有的子数组,然后比较他们的和的大小,如果输入的数组元素个数为N,那么就要有N(N+1)/2个子数组。很明显是不符合要求的。然后我可以用动态规划的思想。假设sum(i)以第i个元素结尾的连续的最大的子数组和。假设i前面的子数组之和都已经求出。那么sum(i)要么就是sum(i-1)和a[i]的和,要么就是a[i]本身,这个取决于Sum(i-1)是否大于0.由于只需要保存前一次的结果,而不需要向其他的动态规划一样保存之前所有的结果,因此时间复杂度很低。
第二种思路:举例分析数组的规律
两者者有异曲同工之妙。
public class subArraySumMax { private boolean isInvaildPut = false;//要来区分无效输入返回的0,还是数组最大值返回为0; public int subArraySumMaxOfArray(int[] a){ if(a==null){ isInvaildPut=true; return 0; } isInvaildPut=false; int curNumber=a[0];//记载当前子数组的和的值 int maxNumber=a[0];//存放子数组最大和的值 for(int i=1;i<a.length;i++){ if(curNumber<=0) curNumber=a[i]; else curNumber+=a[i]; if(curNumber>maxNumber) maxNumber=curNumber; } return maxNumber; } public static void main(String[] args){ int[] a={1,-2,3,10,-4,7,2,-5}; subArraySumMax subMax=new subArraySumMax(); int sum=subMax.subArraySumMaxOfArray(a); System.out.println(sum); } }