侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 675 篇文章
  • 累计创建 128 个标签
  • 累计收到 26 条评论

目 录CONTENT

文章目录

【双指针】日志统计

GabrielxD
2023-02-16 / 0 评论 / 0 点赞 / 229 阅读 / 764 字
温馨提示:
本文最后更新于 2023-02-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

1238. 日志统计 - AcWing题库


小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 NN 行。

其中每一行的格式是:

ts id

表示在 tsts 时刻编号 idid 的帖子收到一个”赞”。

现在小明想统计有哪些帖子曾经是”热帖”。

如果一个帖子曾在任意一个长度为 DD 的时间段内收到不少于 KK 个赞,小明就认为这个帖子曾是”热帖”。

具体来说,如果存在某个时刻 TT 满足该帖在 [T,T+D)[T, T+D) 这段时间内(注意是左闭右开区间)收到不少于 KK 个赞,该帖就曾是”热帖”。

给定日志,请你帮助小明统计出所有曾是”热帖”的帖子编号。

输入格式

第一行包含三个整数 N,D,KN,D,K

以下 NN 行每行一条日志,包含两个整数 tstsidid

输出格式

按从小到大的顺序输出热帖 idid

每个 idid 占一行。

数据范围

1KN1051 \le K \le N \le 10^5,
0ts,id1050 \le ts,id \le 10^5 ,
1D100001 \le D \le 10000

输入样例:

7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3

输出样例:

1
3

解题

方法一:双指针 滑动窗口

思路

【双指针】字符串删减类似都是利用双指针思想,维护一个定长的滑动窗口,然后更新窗口内的计数。不过本题的实现稍微麻烦一点,首先要把输入的日子以时间 ts 为下标把 id 存入数组中(注意同一时间可能有多个 id 所以数组里还得套一层列表),然后维护一个长度为 dd 的滑动窗口,在每次有新的 id 加入窗口时检查该 id 在当前窗口内获点赞的数量,如果大于 k 就放入结果集合(使用树集既去重又排序),最后按顺序输出结果集合即可。

代码

import java.util.*;
import java.io.*;

public class Main {
    static final int N = (int) 1e5 + 10;
    
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        in.nextToken();
        int n = (int) in.nval;
        in.nextToken();
        int d = (int) in.nval;
        in.nextToken();
        int k = (int) in.nval;
        List<Integer>[] logs = new ArrayList[N];
        int sz = 0;
        while (n-- > 0) {
            in.nextToken();
            int ts = (int) in.nval;
            in.nextToken();
            int id = (int) in.nval;
            if (logs[ts] == null) logs[ts] = new ArrayList<>();
            logs[ts].add(id);
            sz = Math.max(sz, ts + 1);
        }
        int[] cnts = new int[N];
        Set<Integer> ans = new TreeSet<>();
        for (int l = 0, r = 0; r < sz; ++r) {
            if (logs[r] != null) {
                for (int id : logs[r]) {
                    if (++cnts[id] >= k) ans.add(id);
                }
            }
            if (r - l + 1 >= d) {
                if (logs[l] != null) {
                    for (int id : logs[l]) --cnts[id];
                }
                ++l;
            }
        }
        for (int id : ans) System.out.println(id);
    }
}
0

评论区