算法-绳子能覆盖最多点的个数(java)

绳子能覆盖最多点的个数

  • 绳子能覆盖最多点的个数
  • 贪心算法
    • 代码演示
  • 贪心解法二
  • 往期经典算法题

绳子能覆盖最多点的个数

给定一个有序数组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;
    }

往期经典算法题

一张纸折叠N次,请从上到下打印所有的:凹凸折痕

二叉树专题-按层遍历

前序中序和后序遍历的递归实现和非递归实现

单链表-快慢指针法来确定链表中间位置.

计算最大线段重合数问题

用栈实现队列和用队列实现栈

你可能感兴趣的:(算法,数据结构,java,算法,java,数据结构,leetcode,开发语言)