算法总结之 未排序数组中累加和小于或等于给定值的最长子数组长度
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法总结之 未排序数组中累加和小于或等于给定值的最长子数组长度相关的知识,希望对你有一定的参考价值。
给定一个无序数组arr,其中元素可正、可负、可0,给定一个整数k,求arr所有的子数组中累加和小于或等于k的最长子数组长度。
例如: arr=[3,-2,-4,0,6] , k=-2, 相加和小于或者等于-2的最长子数组为{3,-2,-4,0}, 所以结果返回4
解题思想:
预处理思想,把信息记录下来
累加和数组的改变
累加和数组中的最大值
用二分查找第一个大于等于某个值的位置
有序适合用二分查找
首先生成 sumArr 就是累加后的数组 这个数组大哦 因为 第一个为0 表示当没有任何一个数时的累加和为0
其次 生成sumArr的左侧最大数helpArr, sumArr={0,1,3,2,7,5} ->help={0,1,3,3,7,7} 我们只关心大于或等于某一个值的累加和最早出现的位置!
helpArr是sumArr每个位置上的左侧最大值数组,那么当然是有序的!
所以可以用二分查找法!查找大于或等于某一个值的累加和最早出现的位置。
package TT; public class Test72 { public static int maxLength(int[] arr, int k ){ int[] h = new int[arr.length+1]; int sum = 0; h[0] = sum; for(int i =0; i !=arr.length; i++){ sum +=arr[i]; h[i+1]=Math.max(sum, h[i]); } sum = 0; int res = 0; int pre = 0; int len = 0; for(int i =0; i!=arr.length; i++){ sum +=arr[i]; pre = getLessIndex(h, sum-k); len = pre == -1 ? 0 : i-pre+1; res = Math.max(res, len); } return res; } public static int getLessIndex(int[] arr, int num){ int low = 0; int high = arr.length-1; int mid = 0; int res=-1; while(low <= high){ mid = (low+high)/2; if(arr[mid]>=num){ res=mid; high=mid-1; }else { low = mid +1; } } return res; } public static void main(String[] args){ int[] arr = new int[5]; arr[0]=3; arr[1]=-2; arr[2]=-4; arr[3]=0; arr[4]=6; int x = maxLength(arr,-2); System.out.println(x); } }
以上是关于算法总结之 未排序数组中累加和小于或等于给定值的最长子数组长度的主要内容,如果未能解决你的问题,请参考以下文章