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个元素的优先队列中做事情,所以,每一步的操作是logk这个级别的。因为要遍历这个元素,所以是O(nlogk)级别的。如果k远远地小于n的话,那么这个时间复杂度非常地好,但是如果k和n差不多的情况下,这个算法的时间复杂度和nlogn的时间复杂度就差不多了。
对于这个问题,也可以设计一个O(nlog(n-k))的算法,换句话说,优先队列中不维护k个元素,而维护n-k个元素来完成这个任务。对于这个算法,如果n和k差不多的话,这个时间优势就非常明显了。
class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
List<Integer> list=new LinkedList();
if(nums.length==0) return list;
Map<Integer,Integer> map=new HashMap();
PriorityQueue<Integer>heap=new PriorityQueue((n1,n2)->
map.get(n1)-map.get(n2));
for(int num:nums){
if(map.containsKey(num)){
map.put(num,map.get(num)+1);
}else{
map.put(num,1);
}
}
for(int key:map.keySet()){
heap.add(key);
if(heap.size()>k)
heap.poll();
}
while(!heap.isEmpty())
list.add(0,heap.poll());
return list;
}
}