每天一道算法题3

【窗口移动】给定一个有序数组arr, 从左到右依次表示X轴上从左往右点的位置,给定一个正整数L,返回如果有一根长度为L的绳子,最多能盖住几个点绳子的边缘点碰到X轴上的点,也算盖住。

方法一: 以第0个点到第n个点,分别以这些点为右边界,找到

public static int maxPoint1(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;
}

方法二:窗口法,先扩大这个窗口的右边界,直到 > L, 然后左边界的下标++, 再次扩右边界。直到左,右边界到头。因为当一个窗口大小 > L 时,左边界右移一位,此时窗口大小缩小,所以右边界无需变化。

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;
}

你可能感兴趣的:(每天一道算法题3)