1. 题目
给定一个有序数组arr
,从左到右依次表示X
轴上从左往右点的位置
给定一个正整数K
,返回如果有一根长度为K
的绳子,最多能盖住几个点绳子的边缘点碰到X
轴上的点,也算盖住。
2. 解释
相当于给了你一个轴,上面有一些点,你在这个轴上选一个位置把绳子钉上,你来或左或右的方向拉这个绳子,怎样让绳子盖住最多的点。
3. 思路
首先边缘的点也算上,我们要想盖住最多,那么就要从点出发。
我们从左往右拉和从右往左拉绳子都是一样的,这里我们就往左拉绳子。这是一个有序数组,那么我们可以使用二分查找,去查这个绳子另一端在什么位置,然后用这个位置减去右侧的位置,就是盖住的数量。
4. 代码
public class Code01_CordCoverMaxPoint {
public static int maxPoint(int[] arr, int L) {
int res = 1;
for(int i = 0; i< arr.length; i++){
int nearest = nearestIndex(arr, i, arr[i] - L);
res = Math.max(res, i - nearest + 1);
}
return res;
}
public static int nearestIndex(int[] arr, int R, int value){
int L = 0;
int index = R;
while(L <= R){
int mid = L + ((R - L) >> 1);
if(arr[mid] >= value){
index = mid;
R = mid - 1;
}else{
L = mid + 1;
}
}
return index;
}
public static int maxPoint2(int[] arr, int L){
int left = 0;
int right = 0;
int N = arr.length;
int max = 0;
while(left < N){
while(right < N && arr[right] - arr[left] <= L){
right++;
}
max = Math.max(max, right - (left ++));
}
return max;
}
public static void main(String[] args) {
int[] arr = {1, 2, 4, 5, 10, 12, 16};
System.out.println(maxPoint(arr, 5));
System.out.println(maxPoint2(arr, 5));
}
}
运行结果:
4
4
5. 总结
就是一个二分查找,很简单。