优先队列(堆排序)或者桶排序
注意一下对于ArrayList数组的创建:ArrayList<Integer>[] list = new ArrayList[nums.length + 1];
/**
* topK问题,使用map记录每个元素出现的频率,然后使用小顶堆或者桶排序即可
* https://leetcode-cn.com/problems/top-k-frequent-elements/solution/leetcode-di-347-hao-wen-ti-qian-k-ge-gao-pin-yuan-/
*/
public class topK {
public static List<Integer> topKFrequent(int[] nums, int k) {
List<Integer> res = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
if (!map.containsKey(num)) map.put(num, 1);
else {
map.put(num, map.get(num) + 1);
}
}
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return map.get(o1) - map.get(o2);
}
});
for (Integer index : map.keySet()) {
if (queue.size() >= k) {
if (map.get(queue.peek()) < map.get(index)) {
queue.poll();
queue.offer(index);
}
} else {
queue.offer(index);
}
}
while (!queue.isEmpty()) {
res.add(queue.poll());
}
return res;
}
public static List<Integer> topKFrequent2(int[] nums, int k) {
List<Integer> res = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
ArrayList<Integer>[] list = new ArrayList[nums.length + 1];
// 统计频率
for (int num : nums) {
if (!map.containsKey(num)) map.put(num, 1);
else map.put(num, map.get(num) + 1);
}
// 向频率桶中加入相应的元素
for (Integer index : map.keySet()) {
int freq = map.get(index);
if (list[freq] == null) list[freq] = new ArrayList<>();
list[freq].add(index);
}
// 从频率最高的桶开始往前查找,找到k个数就结束
for (int i = list.length - 1; i >= 0 && res.size() < k; i--) {
if (list[i] == null) continue;
while (list[i].size() != 0) {
res.add(list[i].remove(0));
}
}
return res;
}
public static void main(String[] args) {
int[] nums = {1, 1, 1, 2, 2, 3};
System.out.println(topKFrequent2(nums, 2));
}
}