LeetCode347.前K个高频元素(hash表+桶排序)
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
1<=nums.length<=1051 <= nums.length <= 10^51<=nums.length<=105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
题解:
这道题思路很明显,首先我们要统计每个元素出现的次数,然后就可以进行排序,选出前k个元素,但是重点就是怎么去实现
首先统计的话肯定是用hash表,元素值为key,出现次数为value。那我们统计完之后如何排序以及获得我们需要的。我们统计的时候是按元素统计的,在排序的时候是要按出现次数排,因此要反过来,那就相当于一个key对应的多个value,比方说出现次数2次的有3和5,这两个都是要记录的,这种情况的话桶排序是比较适合的,每个出现次数当作一个桶,一个桶中有多个元素,具体看代码实现。
代码:
class Solution {public int[] topKFrequent(int[] nums, int k) {// 1. 统计出现次数Map<Integer, Integer> map = new HashMap<>();for(int num : nums){if(map.containsKey(num)){map.put(num, map.get(num) + 1);}else map.put(num, 1);}int maxCnt = Collections.max(map.values());// 2. 创建桶数组List<Integer>[] buckets = new ArrayList[maxCnt + 1];for (int i = 0; i <= maxCnt; i++) {buckets[i] = new ArrayList<>();}for(Map.Entry<Integer, Integer> entry : map.entrySet()){buckets[entry.getValue()].add(entry.getKey());}// 3. 倒序遍历,直到ans长度为kint ans[] = new int[k];for(int i = maxCnt, j = 0; i >= 0 && j < k; i --){for(int x : buckets[i]){ans[j ++] = x;}}return ans;}
}