LeetCode:347. Top K Frequent Elements
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]
给定一个整型数组,求出现频率前k高的数字。
思路一:暴力求解法
先遍历整个数组,记录每个数字出现的个数,再按次数排序。
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
countDict = {}
l = len(nums)
for i in range(l):
if (nums[i] not in countDict):
countDict[nums[i]] = 1
else:
countDict[nums[i]] = countDict[nums[i]] +1
tmp = sorted(countDict.items(),key=lambda x:x[1],reverse=True)
res = []
for i in range(k):
res.append(tmp[i][0])
return res
思路二:堆(Heap)
直接利用大顶堆,维护它的前k大的节点即可。
class Solution:
def topKFrequent(self, nums, k):
count = collections.Counter(nums)
return heapq.nlargest(k, count.keys(), key=count.get)
Python 代码比较抽象,再看一下Java实现:
class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
// Step1. build hash map : character and how often it appears
HashMap<Integer, Integer> count = new HashMap();
for (int n: nums) {
count.put(n, count.getOrDefault(n, 0) + 1);
}
// Step2. init heap 'the less frequent element first'
PriorityQueue<Integer> heap = new PriorityQueue<Integer>((n1, n2) -> count.get(n1) - count.get(n2));
// Step3. keep k top frequent elements in the heap
for (int n: count.keySet()) {
heap.add(n);
if (heap.size() > k)
heap.poll();
}
// Step4. build output list
List<Integer> top_k = new LinkedList();
while (!heap.isEmpty())
top_k.add(heap.poll());
Collections.reverse(top_k);
return top_k;
}
}
注意上面的Step2的实例化优先队列的代码
PriorityQueue<Integer> heap = new PriorityQueue<Integer>((n1, n2) -> count.get(n1) - count.get(n2));
等价与下面的代码:
PriorityQueue<Integer> heap=new PriorityQueue<Integer>(DEFAULT_INITIAL_CAPACITY, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
其实就是用有限队列初始化一个大顶堆。
Step3就是只维护k个节点的大顶堆,从而保证存储的是前k个频率最高的元素。
THE END.