绳子能覆盖最多点的个数
绳子能覆盖最多点的个数
给定一个有序数组arr,代表坐落在X轴上的点,给定一个正数K,代表绳子的长度,返回绳子最多压中几个点?
即使绳子边缘处盖住点也算盖住
贪心算法
我们以数组每个点当做结束节点,然后往前推K,看有几个点能在k的范围内,因为数组是有序的,所以往前推的时候,可以用二分法。每次更新最大值。
时间复杂度 O(n*log n)
代码演示
/**
* 绳子能覆盖的最多节点
* @param arr
* @param L
* @return
*/
public static int maxPoint1(int[] arr, int L) {
int ans = 1;
for (int i = 0; i < arr.length;i++){
int pointNum = getMaxPoint(arr,i,arr[i] - L);
//
ans = Math.max(ans,i - pointNum + 1);
}
return ans;
}
/**
* ,每个节点都当成结尾节点
* 然后用二分法向前推,和value 进行比较,
* @param arr
* @param R
* @param value
* @return
*/
public static int getMaxPoint(int[]arr,int R,int value){
//index 来标记最左边位置
int index = R;
int L = 0;
while (L <= R){
//二分法 获取中间节点
int mid = L + ((R - L) >> 1);
//大于等于value 继续向左移动
if (arr[mid] >= value){
index = mid;
R = mid - 1;
}else{
L = mid + 1;
}
}
return index;
}
贪心解法二
我们以每个节点当做起始节点,然后向右推,不断更新最大值
/**
* 以每个节点当做起始节点,然后向右移动,移动范围在L 范围内,
* 然后遍历每个点,去更新最大值
* @param arr
* @param L
* @return
*/
public static int maxPoint2(int[]arr,int L){
int Left = 0;
int Right = 0;
int N = arr.length;
int ans = 0;
while (Left < N){
//右指针向右移动
while (Right < N && arr[Right] - arr[Left] <= L){
Right++;
}
ans = Math.max(ans,Right - Left);
Left++;
}
return ans;
}