[LeetCode] Top K Frequent Elements 前K个高频元素
相当于组成了个
Given a non-empty array of integers, return the k most frequent elements.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
这道题给了我们一个数组,让我们统计前k个高频的数字,那么对于这类的统计数字的问题,首先应该考虑用HashMap来做,建立数字和其出现次数的映射,然后再按照出现次数进行排序。我们可以用堆排序来做,使用一个最大堆来按照映射次数从大到小排列,在C++中使用priority_queue来实现,默认是最大堆,参见代码如下:
最大堆
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
public int compare(Integer a, Integer b){
return b-a;
}
});
最小堆
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>(); // 小顶堆
for (int val : nums) {
pq.add(val);
if (pq.size() > k) // 维护堆的大小为 K
pq.poll();
}
return pq.peek();
}
当然,既然可以使用最大堆,还有一种可以自动排序的数据结构TreeMap,也是可以的,这里就不写了,因为跟上面的写法基本没啥区别,就是换了一个数据结构。
我们还可以使用桶排序,在建立好数字和其出现次数的映射后,我们按照其出现次数将数字放到对应的位置中去,这样我们从桶的后面向前面遍历,最先得到的就是出现次数最多的数字,我们找到k个后返回即可,参见代码如下:
解法二:
class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
Map<Integer, Integer> mp = new HashMap<>();
for(int num : nums){
mp.put(num, mp.getOrDefault(num,0) + 1);
}
List<Integer>[] bucket = new ArrayList[nums.length + 1];
for(int key : mp.keySet()){
int frequence = mp.get(key);
if(bucket[frequence] == null)
bucket[frequence] = new ArrayList<>();
bucket[frequence].add(key);
}
List<Integer> topk = new ArrayList<>();
for(int i=bucket.length-1; i >=0 && topk.size() < k; i--){
if(bucket[i] == null)
continue;
if(bucket[i].size() <= (k - topk.size()))
topk.addAll(bucket[i]);
else
topk.addAll(bucket[i].subList(0,k-topk.size()));
}
return topk;
}
}
按照字符出现次数对字符串排序
class Solution {
public String frequencySort(String s) {
Map<Character, Integer> mp = new HashMap<>();
for(char num : s.toCharArray()){
mp.put(num, mp.getOrDefault(num,0) + 1);
}
List<Character>[] bucket = new ArrayList[s.length() + 1];
for(char key : mp.keySet()){
int frequence = mp.get(key);
if(bucket[frequence] == null)
bucket[frequence] = new ArrayList<>();
bucket[frequence].add(key);
}
StringBuilder sb = new StringBuilder();
for(int i = bucket.length-1; i >= 1; i--){ //大小记得减回来
if(bucket[i] == null)
continue;
for(char c : bucket[i]){//jizhu这里每个bucket是个arrayList,也是个list
for(int j = i; j >=1; j--)
sb.append(c);
}
}
return sb.toString();
}
}