leetcode 347 C++和kotlin的解法

347. 前 K 个高频元素

中等

1.6K

相关企业

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 105
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

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

先上C++版本的,基本思路是用hashmap统计出现的次数,然后维护一个大小为K的最小堆,最小堆的比较函数使用频率作为比较量。最后,遍历这个最小堆就可以了。其中用到了自定义的pair数据和比较函数。

class Solution {
    typedef pair<int,int> PSI;
    struct cmp
    {
        bool operator()(PSI a, PSI b)
        {
            return a.second>b.second;       // 最小堆
        }
    };
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {

        priority_queue<PSI,vector<PSI>,cmp> pq;
        
        int n=nums.size();
        unordered_map<int,int> Hashmap;
        for(int i=0;i<n;i++)
        {
            Hashmap[nums[i]]++;
        }
        for (auto iter = Hashmap.begin(); iter != Hashmap.end(); ++iter) 
        {
            if(pq.empty() || pq.size()<k){
                pq.push({iter->first,iter->second});
            }
            else if(pq.size()>=k){
                int front = pq.top().first;   //key
                int end = pq.top().second;   //value
                if(iter->second>end){
                    pq.pop();
                    pq.push({iter->first,iter->second});
                }
            }
        }
        vector<int>ans;
        while(!pq.empty())
        {
            ans.push_back(pq.top().first);
            pq.pop();
        }
        return ans;
    }
};

使用kotlin的话,采用如下解法:

解题思路:

  1. 首先统计每个元素出现的频率,使用哈希表进行统计,其中键为元素值,值为出现次数。
  2. 将哈希表中的键值对转化为元素值和出现次数的对应关系的列表。
  3. 对列表按照出现次数进行降序排序。
  4. 取出前 k 个元素的值并返回。

该算法的时间复杂度为 $O(n \log n)$,其中 $n$ 是数组的长度。哈希表的插入操作的时间复杂度为 $O(1)$,排序的时间复杂度为 $O(n \log n)$,取出前 k 个元素的时间复杂度为 $O(k)$。空间复杂度为 $O(n)$。

class Solution {
    fun topKFrequent(nums: IntArray, k: Int): IntArray {
        val map = mutableMapOf<Int, Int>()
        for (num in nums) {
            map[num] = map.getOrDefault(num, 0) + 1
        }

        val list = mutableListOf<Pair<Int, Int>>()
        for (entry in map.entries) {
            list.add(Pair(entry.key, entry.value))
        }

        list.sortByDescending { it.second }
        val result = mutableListOf<Int>()
        for (i in 0 until k) {
            result.add(list[i].first)
        }

        return result.toIntArray()
    }
}

使用kotlin就充分使用了各种数据直接的转换和库函数,写起来确实简明多了。

猜你喜欢

转载自blog.csdn.net/weixin_41579872/article/details/130988381
347