Leetcode 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, 2 和 1 次。

注意:

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

扩展练习:

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

来源:力扣(LeetCode)
链接:
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题报告

两种解法。
第一种时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
第二种时间复杂度为 O ( n l o g k ) O(nlogk) O(nlogk) 要注意第二种方法中重载大小判断运算符的方法。

实现代码

// class Solution {
// public:
//     static bool cmp(paira, pairb){
//         if(a.second!=b.second)
//             return a.second>b.second;//按照第二个元素从小到大排序
//         else return a.first
//     }
//     vector topKFrequent(vector& words, int k) {
//         unordered_mapmp;
//         vectorans;
//         for(int i=0;i
//             mp[words[i]]++;
//         }
//         vector>vec;
//         for(auto m:mp){
//             vec.push_back({m.first, m.second});
//         }
//         sort(vec.begin(), vec.end(), cmp);
        
//         for(int i=0;i
//             ans.push_back(vec[i].first);
//         }
        
//         return ans;
//     }
// };

typedef pair<int,string> P;//频数,单词

struct Order
{//起到greater的作用,如果a的优先级大于b的,返回true
    bool operator()(const P& a,const P& b)const
    {//a,b频数大的,优先级大,频数相等,字典序小的优先级大.
        return (a.first>b.first||(a.first==b.first&&a.second<b.second));
    }
};

class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        vector<string> ans;
        int n=words.size();
        Order ord;//比较器

        //用于统计词频
        unordered_map<string,int> word_freq;
        //遍历统计词频
        for(string x:words)word_freq[x]++;

        //遍历,构造一个大小为k的小顶堆,每次插入元素是O(logk)的,所以建堆是O(nlogk)的
        priority_queue<P,vector<P>,Order> pq;

        for(auto item:word_freq)
        {
            P tmp{item.second,item.first};//当前元素
            //如果没满继续往里加
            if(pq.size()<k)pq.push(tmp);
            //否则队列里元素数目一定>=k
            else if(ord(tmp,pq.top()))
            {//如果tmp的优先级>队首的优先级
                pq.push(tmp);
                pq.pop();//pop掉队首,也就是优先级小的,应该还剩下k个元素
            }    
        }

        //把k个元素逆序输出就好
        while(k--)
        {
            ans.push_back(pq.top().second);
            pq.pop();
        }
        reverse(ans.begin(),ans.end());//O(k)的复杂度

        return ans;
    }
};

// 作者:ydong17
// 链接:https://leetcode-cn.com/problems/top-k-frequent-words/solution/wei-hu-da-xiao-wei-kde-xiao-ding-dui-ji-ke-onlogk-/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考资料

[1] Leetcode 692. 前K个高频单词
[2] 题解区:ydong17

你可能感兴趣的:(leetcode,数据结构)