程序员社区

算法-面试题系列-1-有序数组压中点个数

面试题系列-有序数组压中点个数

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

算法-面试题系列-1-有序数组压中点个数插图
image-20210510174212358

解法思路:

找到单调性

算法-面试题系列-1-有序数组压中点个数插图1
image-20210510175446981
算法-面试题系列-1-有序数组压中点个数插图2
image-20210510175915320
算法-面试题系列-1-有序数组压中点个数插图3
image-20210510180134886
算法-面试题系列-1-有序数组压中点个数插图4
image-20210510180300741
public class Code01_CordCoverMaxPoint {

    //贪心,右侧压中一个,2分查找左侧 时间复杂度O(N*logN)
    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;
    }

    //单调性解法 left right 一次计算往右 事件复杂度O(n)
    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;
    }

    // for test
    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 L = (int) (Math.random() * max);
            int[] arr = generateArray(len, max);
            int ans1 = maxPoint1(arr, L);
            int ans2 = maxPoint2(arr, L);
            int ans3 = test(arr, L);
            if (ans1 != ans2 || ans2 != ans3) {
                System.out.println("oops!");
                break;
            }
        }

    }

}
赞(0) 打赏
未经允许不得转载:IDEA激活码 » 算法-面试题系列-1-有序数组压中点个数

一个分享Java & Python知识的社区