算法题之长度为 K 的绳子,最多能盖住几个点

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. 总结

就是一个二分查找,很简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值