题解 | #未排序数组中累加和小于或等于给定值的最长子数组长度#
未排序数组中累加和小于或等于给定值的最长子数组长度
http://www.nowcoder.com/practice/3473e545d6924077a4f7cbc850408ade
import java.util.*; public class Main{ public static int maxLen1(int[] arr, int k) { if (arr == null || arr.length == 0) { return 0; } int[] minSums = new int[arr.length]; int[] minSumEnds = new int[arr.length]; minSums[arr.length - 1] = arr[arr.length - 1]; minSumEnds[arr.length - 1] = arr.length - 1; for (int i = arr.length - 2; i >= 0; i--) { if (minSums[i + 1] < 0) { minSums[i] = arr[i] + minSums[i + 1]; minSumEnds[i] = minSumEnds[i + 1]; } else { minSums[i] = arr[i]; minSumEnds[i] = i; } } int end = 0; int sum = 0; int res = 0; //i是窗口的最左位置,end是窗口最右位置的下一个位置 从左到右遍历 for (int i = 0; i < arr.length; i++) { /*1、如果以i开头的情况下,累加和<=k的最长子数组是arr[i...end-1],看看是否需要更新res 2、如果以 i开头的情况下,累加和<=k的最长子数组比arr[i...end-1],则不会影响结果 * */ //以i开始,右扩 while (end < arr.length && sum + minSums[end] <= k) { sum += minSums[end]; end = minSumEnds[end] + 1; } res=Math.max(res,end-i); if(end>i){ sum-=arr[i]; //为了下次,以i+1为开头 }else { //窗口内部没有数,说明以i开头的所有子数组的累加和都不可能<=k end=i+1; } } return res; } public static void main(String[] args) { Scanner in=new Scanner(System.in); int n=in.nextInt(); int k=in.nextInt(); int[] arr=new int[n]; for (int i = 0; i <n ; i++) { arr[i]=in.nextInt(); } int res=maxLen1(arr,k); System.out.println(res); } }