题目
数轴上有N个点,求一条长度为K的线段最多覆盖多少个点?
思路
两个指针,i指向头,l指向尾。
如果w[i]-w[l]<k,头i向前移动一步。
如果w[i]-w[l]>=k,尾巴l向前移动一步。
每个数最多遍历2遍,因此时间复杂度为O(n)。
对于这个算法,某网友给了一个形象的比喻:
就好像一条长度为L的蛇。头伸不过去的话,就把尾巴缩过来最多只需要走一次,就知道能覆盖几个点。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int w[100010];
int main()
{
int n;
int k;
cin>>n>>k;
for(int i = 1; i <= n; i++){
cin>>w[i];
}
int l = 1;// 尾
int m = 1;
for(int i=1; i<= n; i++) {//头
while(w[i]-w[l]>=k){
l++;
}
// m = max(m,i-l+1);
if(i-l>=m){
m=i-l+1;
}
}
cout<<m<<endl;
return 0;
}
这道题要点:
1.注意在遍历的时候头和尾都不会后退,所以定义头和尾的初始值时在循环外面定义。
2.题目中给定的数组是有序数组,不用考虑把每两个点的间隔用数组储存起来。。。,这样会把问题复杂化,因为数组是有序数组,刚刚好每一段距离,不管是多远,只需要两个值相减就出来了,同时,我们求每一段距离包含的数字个数,只需要头和尾的指针相减再加一就可以了。
3.注意外层循环最好遍历为头。’