排序/统计处理/初始化/双指针
public static void rizhi() {
int n = 100005;
int[] cnt = new int[n] ;
boolean[] flag = new boolean[n];
int[][] num = new int[n][2];
/**
还可以采用class node{} 的方式来代替创建二维数组,排序方式不变,
但初始化时,可以将公共参数提到外面,并使用static修饰,常数加上final
**/
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int D = sc.nextInt();
int K = sc.nextInt();
for(int i=0;i<N;i++) {
num[i][0] = sc.nextInt();
num[i][1] = sc.nextInt();
}
sc.close();
//排序,按需排序;因为在创建数组的时候不知道具体数组的大小。在输入完成后才知道。
//因此在创建数组的时候,就按1e5+5创建了,但是在排序的时候,没有必要全部排序,
//因为给定了数组索引/输入的行数,因此可以用sort的部分排序的方式来进行排序。
Arrays.sort(num,0,N,new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
return a[0]-b[0];
}
});
for(int i=0,j=0;i<N;i++) {
int id = num[i][1];
cnt[id] ++ ; //将此时间所对应id帖子的点赞数量+1
while(num[i][0]-num[j][0]>=D) {
//因为时间是排好的,且存在双指针,前一个指针总保持满足时间差为D时的状态。
cnt[num[j][1]] -- ;
//在不断更新j指针的同时(即保证了在D的范围),同时对上一条数据(【j】ts,id)
//所对应的不满足的j指针的id的点赞数-1;
j++; //移动j指针,直到满足在D的范围内。
}
if(cnt[id]>=K) flag[id] = true; //使用boolean进行标记,防止同一个id重复输出。
}
for(int i=0;i<=100000;i++) {
if(flag[i]) System.out.println(i);
}
}