[LeetCode] Top K Frequent Elements

简介: Given a non-empty array of integers, return the k most frequent elements.For example, Given [1,1,1,2,2,3] and k = 2, return [1,2].Note: You may assume k is always valid, 1 ≤ k ≤ num

Given a non-empty array of integers, return the k most frequent elements.

For example,
Given [1,1,1,2,2,3] and k = 2, return [1,2].

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.

解题思路

  1. 用一个Map统计每个数字的出现频率。
  2. 依据出现频率对Map.Entry进行排序,排序算法为堆排序。
  3. 输出出现频率最高的k个元素。

实现代码

//Runtime: 43 ms
public class Solution {

    private void buildHeap(ArrayList<Map.Entry<Integer, Integer>> entries, int root, int len) {
        int left = 2 * root + 1;
        if (left < len) {
            int largest = left;
            int right = left + 1;
            if (right < len && entries.get(right).getValue() > entries.get(largest).getValue()) {
                largest = right;
            }
            if (entries.get(root).getValue() < entries.get(largest).getValue()) {
                Map.Entry<Integer, Integer> entry = entries.get(root);
                entries.set(root, entries.get(largest));
                entries.set(largest, entry);
                buildHeap(entries, largest, len);
            }
        }
    }

    private void heapSort(ArrayList<Map.Entry<Integer, Integer>> entries) {
        int len = entries.size();
        for (int i = len / 2; i >= 0; i--) {
            buildHeap(entries, i, len);
        }
        for (int i = len - 1; i > 0; i--) {
            Map.Entry<Integer, Integer> entry = entries.get(0);
            entries.set(0, entries.get(i));
            entries.set(i, entry);
            buildHeap(entries, 0, --len);
        }
    }

    public List<Integer> topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num : nums) {
            if (map.containsKey(num)) {
                map.put(num, map.get(num) + 1);
            } else {
                map.put(num, 1);
            }
        }
        ArrayList<Map.Entry<Integer, Integer>> entries = new ArrayList<Map.Entry<Integer, Integer>>(map.entrySet());
        heapSort(entries);

        List<Integer> list = new ArrayList<Integer>(k);
        for (int i = entries.size() - 1; i >= entries.size() - k; i--) {
            list.add(entries.get(i).getKey());
        }
        return list;
    }
}
目录
相关文章
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
存储 算法 搜索推荐
Leetcode 347.Top K Frequent Elements
一句话理解题意:输出数组中出现次数对多的k个数。 在如果用C语言来写这个题目,思路就是先按数的大小排序,然后再用一个结构体数组保存每个数的出现次次数。 因为数组已经有序了,所以只需要遍历一次数组就可以获得每个数的出现次数了。
52 3
|
机器学习/深度学习 算法 安全
LeetCode - #48 旋转图像(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
LeetCode - #48 旋转图像(Top 100)
|
算法 安全 Swift
LeetCode - #56 合并区间(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
算法 安全 Swift
LeetCode - #53 最大子数组和(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
算法 安全 Swift
LeetCode - #49 字母异位词分组(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
机器学习/深度学习 算法 安全
LeetCode - #46 全排列(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
57 6
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
118 2