zoukankan      html  css  js  c++  java
  • 给定有序数组arr,问K长度的绳子最多盖住几个点


    import java.util.Arrays;

    /**
    * 给定有序数组arr,代表X轴上的点,给定一个正整数K,代表长度为K的绳子,问绳子最多能盖住几个点(绳子边缘碰到也算盖住)
    * <p>
    * 滑动窗口
    */
    public class CoverMostPoint {

    /**
    * 滑动窗口
    *
    * @param arr 数组
    * @param k 长度
    * @return 结果
    */
    public static int coverMostPoint(int[] arr, int k) {
    if (arr == null || arr.length == 0) {
    return 0;
    }
    int left = 0;
    int right = 0;
    int max = 0;
    int length = arr.length;
    while (left < length) {
    while (right < length && arr[right] - arr[left] <= k) {
    right++;
    }
    max = Math.max(max, right - left);
    left++;
    }
    return max;
    }

    /**
    * 用二分法找到 绳子长度内最近的点的下标
    *
    * @param arr 数组
    * @param L 长度
    * @return 结果
    */
    public static int coverMostPoint2(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;
    }

    /**
    * 暴力解,找到以i为结尾,最长能盖住几个点
    *
    * @param arr 数组
    * @param L 长度
    * @return 结果
    */
    public static int test(int[] arr, int L) {
    int max = 0;
    for (int i = 0; i < arr.length; i++) {
    int pre = i - 1;
    while (pre >= 0 && arr[i] - arr[pre] <= L) {
    pre--;
    }
    max = Math.max(max, i - pre);
    }
    return max;
    }

    // for test
    public static int[] generateArray(int len, int max) {
    int[] ans = new int[(int) (Math.random() * len) + 1];
    for (int i = 0; i < ans.length; i++) {
    ans[i] = (int) (Math.random() * max);
    }
    Arrays.sort(ans);
    return ans;
    }

    public static void main(String[] args) {
    int len = 100;
    int max = 1000;
    int testTime = 100000;
    System.out.println("测试开始");
    for (int i = 0; i < testTime; i++) {
    int k = (int) (Math.random() * max);
    int[] arr = generateArray(len, max);
    int ans1 = coverMostPoint(arr, k);
    int ans2 = coverMostPoint2(arr, k);
    int ans3 = test(arr, k);
    if (ans1 != ans2 || ans2 != ans3) {
    System.out.println("oops!");
    break;
    }
    }
    System.out.println("测试结束");

    }

    }

    /* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */
  • 相关阅读:
    day19 MRO C3算法 super()
    日志的处理
    day18 约束 异常
    Android-多线程和进程
    Android-多线程Handler
    hdu 1561 树形背包 选k个最大价值
    poj 1947 树形背包 (删边)
    hdu 1011 树形背包
    poj 1155 树形背包
    hdu 3535 (最少1,最多1,任意)(背包混合)(好题)
  • 原文地址:https://www.cnblogs.com/laydown/p/14092244.html
Copyright © 2011-2022 走看看