Leetcode前 K 个高频元素

109 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

例1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

例2:

输入: nums = [1], k = 1
输出: [1]

进阶: 你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。

二、解题思路

先去看了一波标签,好家伙,数组、哈希表、分治、桶排序、计数、快速选择、排序、堆(优先队列)。其实这道题分两步,先遍历计一遍数然后再排序找出前k大,这里排序最快的方法是建个堆,而JS没有,所有打算用python,转念一想python有个非常适合这道题的数据结构Counter,于是写了个偷懒版的(但是使用堆也算是用轮子,只是封装的程度不同罢了)。

三、AC代码

from collections import Counter
class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        c = Counter()
        for item in nums:
            c[item] += 1
        res = [i[0] for i in c.most_common(k)]
        return res

四、总结

贴一个比较规整的使用最大堆的答案:

    public int[] topKFrequent(int[] nums, int k) {
        //先统计每个数字出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        for (int num : nums)
            map.put(num, map.getOrDefault(num, 0) + 1);

        //最大堆
        PriorityQueue<int[]> priorityQueue = new PriorityQueue<>((a, b) -> b[1] - a[1]);
        for (int key : map.keySet())
            priorityQueue.add(new int[]{key, map.get(key)});

        //取堆中最大的k个元素
        int[] res = new int[k];
        for (int i = 0; i < k; i++)
            res[i] = priorityQueue.poll()[0];
        return res;
    }

作者:数据结构和算法
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvzpxi/?discussion=qfyTUW