【蓝桥杯】求子数组最大累积和
题目描述:给定一个数组arr,返回子数组的最大累计和。
例如arr=[1,-2,3,5,-2,6,-1],返回12.(因为子数组[3,5,-2,6]累积和最大。)
拓展:试求出累计和最大的子数组
分析:
思路1:使用双指针,暴力破解,逐个累积求和。
1 private static void solve1(int[] arr) { 2 int maxSum=arr[0]; 3 // int left=0,right=0;//记录子数组累加和最大的子数组下标 4 for(int j=0;j<arr.length;j++){ 5 int sum=arr[j];//j为哨兵,为子数组的第一个元素; 6 int maxOfJ=sum;//把目前的和看作给这个子数组的最大值 7 for(int i=j+1;i<arr.length;i++){ 8 sum+=arr[i];//i为游标 9 if(sum>maxOfJ){ 10 maxOfJ=sum; 11 // right=i;//i是移动的,子数组结束一定从i这结束 12 } 13 } 14 if(maxOfJ>maxSum){ 15 maxSum=maxOfJ; 16 // left=j;//最大子数组开始的下标一定是哨兵处; 17 18 } 19 20 } 21 22 System.out.println(maxSum); 23 // printSub(arr,left,right); 24 // System.out.println(left+","+right); 25 }
思路2:递推法。只有当前面的和sum大于0才累加,否则抛弃前面所求的和,从该点开始向后求和。
1 //dp递推法 2 private static void solve2(int[] arr) { 3 int sum=arr[0]; 4 int max=sum; 5 int left=0,right=0; 6 int sumJ = 0 ; 7 for (int j = 1; j < arr.length-1; j++) { 8 if(sum>=0){ 9 sum+=arr[j]; 10 11 }else{ 12 sum=arr[j]; 13 left=j; 14 } 15 16 if(sum>max){ 17 max=sum; 18 right=j; 19 } 20 } 21 22 System.out.println(max); 23 printSub(arr,left,right); 24 System.out.println(left+","+right); 25 }
打印子数组的函数
1 //打印子数组累加和最大的子数组; 2 private static void printSub(int[] arr, int left, int right) { 3 4 System.out.print("["); 5 // if(left>right){ 6 // System.out.print(arr[left]); 7 // } 9 for(int x=left;x<=right;x++){ 10 if(left==right){ 11 System.out.print(arr[left]); 12 break; 13 } 14 15 System.out.print(arr[x]); 16 if(x!=right){ 17 System.out.print(","); 18 } 19 20 } 21 System.out.println("]"); 22 }
测试用例:
1 //int []arr={1,-2,3,5,-2,6,-1};//12 2 //int []arr={-1,-2,-3,-5,0,-6,-1};//0 3 //int[] arr={-1,-2,-3,-5,-6,-6,-1};//-1 4 int []arr={-1,-2,-3,-1,-2,-1,-1};//-1 5 solve1(arr); 6 System.out.println("#############"); 7 solve2(arr); 8
持续更新中……
浙公网安备 33010602011771号