[LeetCode] 347. Top K Frequent Elements

Posted aaronliu1991

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 347. Top K Frequent Elements相关的知识,希望对你有一定的参考价值。

前K个高频元素。题意是给一个非空数组,请返回前K个高频元素。题目要求时间复杂度必须优于O(nlogn)。例子,

Example 1:

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Example 2:

Input: nums = [1], k = 1
Output: [1]

因为题目有时间复杂度的要求所以只能是bucket sort桶排序的思想做。这题Java的时间复杂度稍稍优于JS,是因为实现方式的不同导致。

Java时间O(n),JS时间O(logn)

空间O(n)

解释一下思路,既然是桶排序,所以需要将出现频率一样的元素放到同一个桶里面,所以这里会用到一个hashmap记录数字和他们各自出现频率(key:value)。接着就需要根据频率大小,挑出前K个频率最大的元素。在JS里面,map是可以根据value排序的(21行),排序完之后,可以根据排序结果,再反过来挑出前K个key(24行)。因为21行用到了快排quick sort,所以时间复杂度至少为O(logn)。

 1 /**
 2  * @param {number[]} nums
 3  * @param {number} k
 4  * @return {number[]}
 5  */
 6 var topKFrequent = function (nums, k) {
 7     // corner case
 8     if (!nums || !nums.length) {
 9         return [];
10     };
11 
12     // normal case
13     let map = new Map();
14     nums.forEach((item) => {
15         if (map.has(item)) {
16             map.set(item, map.get(item) + 1);
17         } else {
18             map.set(item, 1);
19         }
20     })
21     let res = [...map].sort((a, b) => b[1] - a[1]);
22     console.log(res);
23     res = res.map(item => item[0]);
24     return res.slice(0, k);
25 };

 

在Java里面这一题的实现方式略有不同。依然是需要创建一个hashmap记录元素和其频率(第9行)。之后创建桶需要用到一个list,每一个index上连着一个linkedlist,记录同样频率的元素都有哪些(12行)。因为桶排序的桶是按照频率有序排列的,所以最后输出结果的时候可以按桶频率由大到小依次将桶内元素加入结果集(20行)。

 1 class Solution {
 2     public List<Integer> topKFrequent(int[] nums, int k) {
 3         HashMap<Integer, Integer> map = new HashMap<>();
 4         for (int num : nums) {
 5             map.put(num, map.getOrDefault(num, 0) + 1);
 6         }
 7 
 8         List<Integer>[] bucket = new List[nums.length + 1];
 9         for (int num : map.keySet()) {
10             int freq = map.get(num);
11             if (bucket[freq] == null) {
12                 bucket[freq] = new LinkedList<>();
13             }
14             bucket[freq].add(num);
15         }
16 
17         List<Integer> res = new ArrayList<>();
18         for (int i = bucket.length - 1; i >= 0 && res.size() < k; i--) {
19             if (bucket[i] != null) {
20                 res.addAll(bucket[i]);
21             }
22         }
23         return res;
24     }
25 }

 

以上是关于[LeetCode] 347. Top K Frequent Elements的主要内容,如果未能解决你的问题,请参考以下文章

#Leetcode# 347. Top K Frequent Elements

Leetcode 347: Top K Frequent Elements

LeetCode OJ 347. Top K Frequent Elements hashmap+排序求解

leetcode347 - Top K Frequent Elements - medium

Leetcode_347_Top K Frequent Elements

Leetcode_347_Top K Frequent Elements