347. 前 K 个高频元素
https://leetcode.cn/problems/top-k-frequent-elements/
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入:nums = [1,1,1,2,2,3], k = 2
输出:[1,2]
示例 2:
输入:nums = [1], k = 1
输出:[1]
示例 3:
输入:nums = [1,2,1,2,1,2,3,1,3,2], k = 2
输出:[1,2]
import java.util.*;public class hot347 {//最小堆//时间复杂度O(nlogk)public int[] topKFrequent(int[] nums, int k) {// 1. 统计每个元素的频率Map<Integer, Integer> map = new HashMap<>();for (int num : nums) {map.put(num, map.getOrDefault(num,0) + 1);}// 2. 使用最小堆维护前k个高频元素// 堆中存储的是 [元素值, 频率],按频率升序排列PriorityQueue<int[]> queue = new PriorityQueue<>(((a,b) -> a[1] - b[1]));// 3. 遍历频率映射,维护大小为k的最小堆for (Map.Entry<Integer,Integer> entry : map.entrySet()){Integer num = entry.getKey();Integer frequency = entry.getValue();if (queue.size() < k){queue.offer(new int[] {num, frequency});} else if(frequency > queue.peek()[1]){queue.poll();queue.offer(new int[] {num, frequency});}}// 4. 获取结果int[] res = new int[k];for (int i = 0; i < k; i++) {res[i] = queue.poll()[0];}return res;}//桶排序//时间复杂度O(n)public int[] topKFrequent2(int[] nums, int k) {// 1. 统计频率Map<Integer, Integer> frequencyMap = new HashMap<>();for (int num : nums) {frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);}// 2. 创建桶数组,索引表示频率,值为该频率的元素列表List<Integer>[] buckets = new List[nums.length + 1];for (int i = 0; i <= nums.length; i++) {buckets[i] = new ArrayList<>();}// 3. 将元素放入对应频率的桶中for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {int num = entry.getKey();int frequency = entry.getValue();buckets[frequency].add(num);}// 4. 从高频率到低频率收集结果int[] result = new int[k];int index = 0;for (int i = buckets.length - 1; i >= 0 && index < k; i--) {for (int num : buckets[i]) {result[index++] = num;if (index == k) {break;}}}return result;}
}