大家好,我是晴天学长,滑动窗口也是一个经典的双指针的问题,需要的小伙伴请自取哦!💪💪💪
1 )日志统计
2) .算法思路
日志统计
1.接收一个N行 D时间段 k个赞和一个标记数组
建立hashmap范围开大一点也行
2.建立滑动窗口(统计范围是min到max)
大小为D
l=min,r=max
先遍历一遍滑动窗口 统计D时间秒收到的点赞数,符合就标记为ture。
符合条件的话,输出该编号,并删除
移动 l+1 r+1 删除l的统计数 增加r+1的统计数
再次遍历,输出
直到D等于max
3).代码示例
package LanQiaoTest.双指针.滑动窗口;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class 日志统计 {
static int N = 100001;
static long[] ID = new long[N];
static boolean[] IDre = new boolean[N];
//统计答案
static Map<Integer, List<Integer>> map= new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
String[] strings = in.readLine().split(" ");
int n = Integer.parseInt(strings[0]);
int D = Integer.parseInt(strings[1]);
int k = Integer.parseInt(strings[2]);
//统计ts秒有多少文章被点赞了
int max = 0;
int min = 10000;
for (int i = 0; i < n; i++) {
strings = in.readLine().split(" ");
int ts = Integer.parseInt(strings[0]);
min= Math.min(min,ts);
max= Math.max(max, ts);
int id = Integer.parseInt(strings[1]);
if (!map.containsKey(ts)) {
map.put(ts, new ArrayList<>());
}
map.get(ts).add(id);
}
//滑动窗口的初始化
int l=min;
int r=min+D;
//遍历D时间段的日志点赞数
for (int i = l; i < r; i++) {
//遍历map,统计D时间段内的统计数
if (map.containsKey(i)) {
List<Integer> list = map.get(i);
for (int j = 0; j < list.size(); j++) {
int temp2 = list.get(j);
ID[temp2]++;
//判断是否是热帖
if (ID[temp2]>=k) {
IDre[temp2] =true;
}
}
}
}
//滑动窗口的滑动,并统计一次热帖
while (r<max) {
l++;
if (map.containsKey(l-1)) {
List<Integer> list1 = map.get(l-1);
for (int i1 = 0; i1 < list1.size(); i1++) {
int temp3 = list1.get(i1);
ID[temp3]--;
}
}
if (map.containsKey(r)) {
List<Integer> list2 = map.get(r);
for (int i = 0; i < list2.size(); i++) {
int temp4 = list2.get(i);
ID[temp4]++;
if (ID[temp4]>=k) {
IDre[temp4] = true;
}
}
}
r++;
}
//输出文章为true的编号
for (int i = min; i <=max; i++) {
if (IDre[i]==true) {
out.println(i);
}
}
out.flush();
}
}
4).总结
1.滑动窗口(注意窗口大小和移动中数组元素的变化)
- 滑动窗口的初始化
- 滑动窗口的移动
2.要是有编号而且还是有顺序的话,直接用
数组的下标作为编号,然后统计。