一、题目描述
给定一个有序数组arr,代表坐落在X轴上的点,给定一个正数K,代表绳子长度,返回绳子最多压中几个点,绳子边缘处盖住绳子也算盖住。
二、题解
2.1 二分法
思路:
依次以数组中的每个点作为绳子的起点,绳子的起点位置加上绳子的长度为绳子的终点位置,计算出起点与终点之间绳子覆盖了多少个点,因为数组是有序的,所以在计算起点与终点之间绳子覆盖多少个点时,可通过二分查找法
时间复杂度:O(N*logN)
💥
public static int binarySearch(int[] arr,int i,int L){
int left=i;
int right= arr.length-1;
int target=arr[i]+L;
int ans=-1;
while (left<=right){
int mid=left+((right-left)>>1);
if(arr[mid]<=target){
ans=mid;
left=mid+1;
}else{
right=mid-1;
}
}
return ans;
}
public static int maxCoverPoint2(int[] arr,int L){
if(arr==null||arr.length==0||L<=0){
return 0;
}
int max=0;
for (int i = 0; i < arr.length; i++) {
int right=binarySearch(arr,i,L);
max=Math.max(max,right-i+1);
}
return max;
}
2.2 双指针法(滑动窗口)
思路:
定义两个指针L,R,L起出指向数组中的第一个点,R向右移动,直到移动到arr[R]-arr[L]>绳子长度的时候,R就停止移动,计算并保存覆盖的点的数目,之后L指向数组中的下一个点,R同样往后移动,以此类推
时间复杂度:O(N)
💨
public static int maxCoverPoint1(int[] arr,int L){
if(arr==null||arr.length==0||L<=0){
return 0;
}
int left=0;
int right=0;
int max=0;
while (left< arr.length){
while(right<arr.length&&arr[right]-arr[left]<=L){
right++;
}
max=Math.max(max,right-left);
left++;
}
return max;
}