算法1-绳子边缘覆盖

题目

给定一个有序数组arr,代表坐落在X轴上的点;给定一个正数K,代表绳子的长度;返回绳子最多压中几个点?即使绳子边缘处盖住点也算盖住

先贪心后优化思路

先假设每一个点都是绳子末尾点,也就是绳子的最右点,根据绳长往左推,查看绳子盖住了多少点。
所谓的贪心是指,绳子的末尾点不必盖住一个不存在的点,只需盖住实点的位置,继而往前推。

举例假设

假如给定一个有序数组,绳长100,绳子的末尾点来到了973,那么开头点最多来到873(误区:不是874,因为绳子前后边缘部分盖住的都算)。

那么查找有多少个实点是大于等于873,数量+1(因为973也是一个实点)就是答案。

时间复杂度

怎么查找呢?

二分查找

在一个有序数组里,查找大于等于873,用二分查找法。
把每一个实点都当作是绳子的末尾点,每一次查找都来一个二分,每一次的时间复杂度都是logN,那么总体的时间复杂度是
O(N*logN)
在这里插入图片描述

双指针

左右指针,类似滑动窗口,当left来到第1个位置,right指针根据绳长,依次向右滑动,直至到达绳子的尾端。
left和right指针一直往前走,不会后退,那么时间复杂度是O(N)

package demo;

public class One {
	public int maxPoints(int[] arr,int L) {
		int left=0;
		int right=0;
		int max=0;
//		用while循环,每一次都要比较max
		while(left<arr.length) {
//			当右指针小于数组长度,且,左右指针间隔距离《=L,右指针才能继续移动
			 while(right<arr.length&&arr[right]-arr[left]<=L) {
				 right++;
			 }
//			 当移动到不能再移动的时候,这一次的移动和上一次的移动距离作比较
//			 左指针移动一位
//			 max=Math.max(max, right-(left++));
			 max=Math.max(max, right-left);
			 left++;
//			 System.out.println("right"+right);
		}
		return max;
	}
	public static void main(String[] args) {
		One one=new One();
		int[] arrs= {2,4,5,8,9,12,14,15,16,17,18,20};
//		长度为4的可以盖住5个连续的点
		int l=4;
		System.out.println(one.maxPoints(arrs, l));
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值