标题:日志统计
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。其中每一行的格式是:
ts id
表示在ts时刻编号id的帖子收到一个"赞"。
现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为D的时间段内收到不少于K个赞,小明就认为这个帖子曾是"热帖"。
具体来说,如果存在某个时刻T满足该帖在[T, T+D)这段时间内(注意是左闭右开区间)收到不少于K个赞,该帖就曾是"热帖"。
给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。
【输入格式】
第一行包含三个整数N、D和K。
以下N行每行一条日志,包含两个整数ts和id。
对于50%的数据,1 <= K <= N <= 1000
对于100%的数据,1 <= K <= N <= 100000 0 <= ts <= 100000 0 <= id <= 100000
【输出格式】
按从小到大的顺序输出热帖id。每个id一行。
【输入样例】
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
【输出样例】
1
3
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
public class 日志统计 {
/**
* @param args
*/
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();//帖子总数量
int d=sc.nextInt();//区间长度
int k=sc.nextInt();//不少于k个赞
Map<Integer,Integer> m=new TreeMap<>(new Comparator<Integer>() {
//重写compare方法,使Treemap可以放入相同健值的条目
@Override
public int compare(Integer o1, Integer o2) {
if(o1.equals(o2)){
return 1;//return 0;
}else {
return o1-o2;
}
}
});
for (int i = 1; i <= n; i++) {
int ts=sc.nextInt();
int id=sc.nextInt();
m.put(id,ts);
}
int x[]=new int[100001];//记录满足所有题干条件的id值
int num=0;//id数量
//遍历id
for (int id = 1; id < x.length; id++) {
if(check(m,id,d,k)){//是否满足
x[++num]=id;
}
}
//遍历输出结果
for (int i = 1; i <= num; i++) {
System.out.println(x[i]);
}
}
/**
* 确定此id是否为满足题干条件的id
* @param m 存储
* @param i id
* @param d 区间长度
* @param k 最少的赞个数
* @return
*/
private static boolean check(Map<Integer, Integer> m, int i, int d, int k) {
int count=0;//记录id出现的个数
LinkedList<Integer> list=new LinkedList<>();
for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
if(entry.getKey()==i){
count++;
list.add(entry.getValue());//将key值也就是id,添加的list中
}
}
if(count<k){//id的个数小于要求的 最小赞的个数k
return false;
}
Collections.sort(list);
int st=0;//初始指针
int en=0;//结束指针
int sum=0;//当前赞的个数和
while (st<=en && en<list.size()) {
sum++;
if(sum>=k){//如果当前的赞的个数 >=k,也就是不少于k个赞
//判断时间区间是否符合在[T,T+d)之中
if(list.get(en)-list.get(st) < d){
return true;
}else {//不符合
st++;//初始指针右移
sum--;//当前赞数减1
}
}
//每次en指针都会右移,直到到达结尾
en++;
}
//如果超出了while循环的条件仍然没有返回的值,那么此id就不是‘热帖’
return false;
}
}