📅  最后修改于: 2023-12-03 15:04:43.106000             🧑  作者: Mango
查询用 K 替换给定索引后 Array 中最频繁的元素
给定一个整数数组和一个索引,将该索引处的元素替换为指定的值 K,然后计算数组中最常见的元素。如果有多个元素出现同样的次数,则返回其中任意一个。
第一行包含一个整数 N,表示数组的长度。
第二行包含 N 个整数,表示数组中的元素。
第三行包含一个整数 Q,表示询问次数。
接下来 Q 行,每行包含三个整数类型的值:pos,val 和 k,其中 pos 表示索引位置,val 表示将该位置的元素替换为 val,k 表示查询用 K 替换给定索引后 Array 中最频繁的元素。
6
1 2 3 4 5 6
3
0 1 1
5 6 7
2 1 4
1
7
1
算法思路:
首先,我们需要一个哈希表,以便能够在常数时间内快速查找某个元素是否在数组中出现过。
然后,我们需要一个桶来记录每个元素在数组中出现的次数。
接下来,我们需要一个最大堆,以便能够快速找到出现次数最多的元素。
最后,我们使用上述数据结构,并对原本的数组进行修改,然后在桶和最大堆中更新相应的元素和元素出现的次数,最后从最大堆中取出堆顶元素即为出现次数最多的元素。
下面是具体的代码实现,其中用到了 HashMap,PriorityQueue 和 int[] 数组等数据结构:
import java.util.*;
public class Main {
// 全局变量
static int[] nums;
static int n;
static HashMap<Integer, Integer> map = new HashMap<>();
static PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return b[1] - a[1]; // 将出现次数多的元素放在前面
}
});
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt(); // 初始化数组
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); // 初始化哈希表
}
for (Integer key : map.keySet()) {
queue.offer(new int[] { key, map.get(key) }); // 初始化最大堆
}
int q = sc.nextInt();
while (q-- > 0) {
int pos = sc.nextInt();
int val = sc.nextInt();
int k = sc.nextInt(); // 输入
update(pos, val, k); // 更新
System.out.println(queue.peek()[0]); // 输出
}
}
public static void update(int pos, int val, int k) {
// 从哈希表和桶中删除旧值,更新最大堆,然后将新值放入哈希表和桶中,再更新最大堆
map.put(nums[pos], map.get(nums[pos]) - 1);
int[] arr = queue.poll();
arr[1]--;
if (arr[1] > 0) {
queue.offer(arr);
}
map.put(val, map.getOrDefault(val, 0) + 1);
queue.offer(new int[] { val, map.get(val) });
nums[pos] = val;
}
}