1. question: 前K个高频元素(中等)
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/top-k-frequent-elements
示例 1:
1 2
| 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
|
示例 2:
1 2
| 输入: nums = [1], k = 1 输出: [1]
|
提示:
1 2 3
| 1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
|
2. answers
这道题分为两部分,一部分是统计元素数量,另一部分是对元素数量进行排序,取前k个。
统计元素数量可以采用Map数据结构来做;对Map元素进行排序,这里参考博客,可以利用堆来做(优先级队列)。
代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class Solution_0031 {
public static int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>(); int[] result = new int[k];
for(int i: nums) {
if(map.containsKey(i)) { map.put(i, map.get(i) + 1); } else { map.put(i, 1); }
}
Set<Map.Entry<Integer, Integer>> entries = map.entrySet(); PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue()); for (Map.Entry<Integer, Integer> entry : entries) { queue.offer(entry); if (queue.size() > k) { queue.poll(); } }
for (int i = k - 1; i >= 0; i--) { result[i] = queue.poll().getKey(); }
return result; }
public static void main(String[] args) { System.out.println();
int[] nums = {1, 1, 1, 2, 3, 3};
int[] result = topKFrequent(nums, 2);
for(int i: result) { System.out.println(i); } } }
|
另外,参考题解,可采用桶排序来做。在统计完频率后,新建一个新数组,数字的频率就是该数字在新数组中的下标,因为不同数字的频率可能会重复,所以新数组是一个List数组。频率越高,其下标位置越大。最后逆序遍历新数组即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| public class Solution_0031_02 {
public static int[] topKFrequent(int[] nums, int k) {
int[] r = new int[k];
Map<Integer, Integer> result = new HashMap<>();
for(int i: nums) {
if(result.containsKey(i)) result.put(i, result.get(i) + 1); else result.put(i, 1);
}
Set<Integer> integers = result.keySet();
ArrayList<Integer>[] temp = new ArrayList[nums.length + 1];
ArrayList<Integer> list;
for(Integer i: integers) {
int index = result.get(i);
if(temp[index] == null) { list = new ArrayList<>(); } else { list = temp[index]; }
list.add(i); temp[index] = list; }
k --; while(k >= 0) {
for (int i = temp.length - 1; i > -1 ; i--) {
if(temp[i] == null) continue;
for(Integer j: temp[i]) {
r[k--] = j; }
if(k < 0) break; } }
return r; }
public static void main(String[] args) {
int[] nums = {1}; int k = 1;
int[] result = topKFrequent(nums, k);
for(int i: result){ System.out.print(i + "\t"); } } }
|
3. 备注
参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com),代码随想录 (programmercarl.com)。