【LeetCode】347.前K高频元素 优先队列 前K问题

347. 前 K 个高频元素

347. 前 K 个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
 
提示:
你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
你可以按任意顺序返回答案
// 时间复杂度:O(nlogk)
// 空间复杂度:O(n)
class Solution {
    
    
public:
    // 小顶堆
    class mycomparison {
    
    
    public:
        bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
    
    
            return lhs.second > rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
    
    
        // 要统计元素出现频率
        unordered_map<int, int> map; // map<nums[i],对应出现的次数>
        for (int i = 0; i < nums.size(); i++) {
    
    
            map[nums[i]]++;
        }

        // 对频率排序
        // 定义一个小顶堆,大小为k
        priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;
        
        // 用固定大小为k的小顶堆,扫面所有频率的数值 
        for (unordered_map<int, int>::iterator it = map.begin(); it != map.end(); it++) {
    
    
            pri_que.push(*it);
            if (pri_que.size() > k) {
    
     // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                pri_que.pop();
            }
        }

        // 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
        vector<int> result(k);
        for (int i = k - 1; i >= 0; i--) {
    
    
            result[i] = pri_que.top().first;
            pri_que.pop();
        }
        return result;

    }
};

692. 前K个高频单词

692. 前K个高频单词
给一非空的单词列表,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。

示例 1:

输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i""love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i""love" 之前。
 

示例 2:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny""day" 是出现次数最多的四个单词,
    出现次数依次为 4, 3, 21 次。
 

注意:

假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。
输入的单词均由小写字母组成。
 

扩展练习:

尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。

class Solution {
    
    
public:
    class mycomparison{
    
    
        public:
        bool operator()(pair<string,int>& p1,pair<string,int>& p2){
    
    
            if(p1.second==p2.second)
            return p1.first<p2.first;
            return p1.second>p2.second;
            
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
    
    
        unordered_map<string,int> um;
        for(int i=0;i<words.size();i++)
        um[words[i]]++;

        priority_queue<pair<string,int>,vector<pair<string,int>>,mycomparison> pri_que;
    //priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;

        for(unordered_map<string,int>::iterator it=um.begin();it!=um.end();it++){
    
    
            pri_que.push(*it);
            if(pri_que.size()>k)
            pri_que.pop();
        }

        vector<string> res(k);
        for(int i=k-1;i>=0;i--){
    
    
            res[i]=pri_que.top().first;
            pri_que.pop();
        }
        return res;
    }
};

215. 数组中的第K个最大元素

215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

通过次数202,823提交次数315,144
class Solution1 {
    
    
public:
    int findKthLargest(vector<int>& nums, int k) {
    
    
        sort(nums.begin(),nums.end());
        int n=nums.size();
        return nums[n-k];
    }
};

class Solution {
    
    
public:
    class mycomparison{
    
    
        public:
        bool operator()(int a,int b){
    
    
            return a>b;
        }
    };

    int findKthLargest(vector<int>& nums, int k) {
    
    
        priority_queue<int,vector<int>,mycomparison> pri_que;
        for(int i=0;i<nums.size();i++){
    
    
            pri_que.push(nums[i]);
            if(pri_que.size()>k)
            pri_que.pop();
        }
        return pri_que.top();
    }
};

猜你喜欢

转载自blog.csdn.net/qq_37581730/article/details/108658448