当前位置: 首页 > news >正文

算法日常・每日刷题--<优先级队列>3

692. 前K个高频单词 - 力扣(LeetCode)692. 前K个高频单词 - 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。 示例 1:输入: words = ["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 次。 注意: * 1 <= words.length <= 500 * 1 <= words[i].length <= 10 * words[i] 由小写英文字母组成。 * k 的取值范围是 [1, 不同 words[i] 的数量] 进阶:尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。https://leetcode.cn/problems/top-k-frequent-words/

题目描述

给定一个单词列表words和一个整数k,返回前k个出现次数最多的单词。

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

示例 1 输入:words = ["i","love","leetcode","i","love","coding"], k = 2输出:["i","love"]解析:i、love 都出现 2 次,频次相同按字典序,i排在love前面。

题目核心两点:

  1. 出现频次降序
  2. 频次相等,按字典序升序

解题思路:哈希统计 + 优先队列 (小根堆) topK

  1. 哈希表统计频次unordered_map<string, int>遍历所有单词,统计每个单词出现次数。
  2. 小根堆筛选 Top‑K
    • 求前 K 个最大元素,使用小根堆,堆中最多保存 k 个元素;
    • 堆顶维护当前 k 个里面 “最差” 元素,当堆大小 > k,直接弹出堆顶,淘汰掉最差;
    • ⚠️重点:自定义比较器,处理双重排序规则(频次、字典序)。
  3. 结果倒序输出:小根堆堆顶是 k 个里面频次最低的,从后往前填充结果数组,得到从高频到低频的答案。

💡topK 口诀:求前 K 大,用小根堆;求前 K 小,用大根堆。堆顶存放待淘汰元素,容量超限直接 pop 堆顶。

⚠️C++priority_queue底层是大根堆,自定义cmp比较器有特殊规则:cmp(a,b)返回true代表:a 优先级低于 b,b 放到堆顶

class Solution { public: typedef pair<string,int> PSI; struct cmp{ bool operator()(const PSI&a,const PSI&b) { if(a.second==b.second) { return a.first<b.first; } return a.second>b.second; } }; vector<string> topKFrequent(vector<string>& words, int k) { unordered_map<string,int>hash; for(auto& e:words) hash[e]++; priority_queue<PSI,vector<PSI>,cmp>heap; for(auto &e:hash) { heap.push(e); if(heap.size()>k) heap.pop(); } vector<string> ret(k); for(int i=k-1;i>=0;i--) { ret[i]=heap.top().first; heap.pop(); } return ret; } };
http://www.jsqmd.com/news/1395958/

相关文章:

  • MTK 解锁新姿势:mtkclient-gui 图形化工具快速上手指南
  • FlashAttention 源码级深度解析:从 IO 感知 Tiling 与 Online Softmax 到 Hopper/Blackwell 异步流水线的注意力内核底层原理
  • Excel数据查询系统构建指南:VLOOKUP、XLOOKUP与INDIRECT函数实战应用
  • Git回退与重置操作详解:从Rollback到Reset HEAD的完整指南
  • Windows CMD中Curl的完整指南:安装、使用与自动化实战
  • 从APMCM奖励细则看数学建模竞赛备赛策略与价值
  • 网管与非网管交换机核心差异解析:从原理到选型实战指南
  • 从零到一发布npm包:完整流程、核心配置与避坑指南
  • XPT转SAS数据格式转换实战:SAS、Python与R方案详解
  • 长线缆驱动电机四大核心问题与系统性解决方案
  • 【企业知识助手·Agent 实战】如何划定知识助手的 Agent 能力边界:从意图识别、语义路由到兜底降级的深度实战
  • Suno Studio 2.0前瞻:AI音乐生成原理、Prompt工程与API集成指南
  • ComfyUI性能优化:揭秘“第二次快一倍”背后的四阶段缓存机制
  • Grok Build内置/tour教程:终端交互式学习命令行工具
  • Hive UDF/UDTF/UDAF:从核心原理到生产级实现与调优
  • 网络安全基础与核心防范技术详解
  • 双屏扩展模式故障排查:从硬件连接到驱动设置的完整解决方案
  • IDEA集成GitLab全流程指南:从配置到高级协作开发
  • Python环境管理:解决pandas安装成功但导入失败的完整指南
  • 构建可持续激励生态:从励志奖励到创新支持的顶层设计与运营实践
  • 扩散语言模型扩展定律揭秘:LLaDA MoE v2如何重塑文本生成技术路线
  • 从Oracle JDK 8迁移至OpenJDK 17:实战指南与避坑全记录
  • 从零开始用HTML/CSS/JS搭建个人网站:新手完整实战指南
  • 手机摄影中的色块日常:从观察到后期的完整创作指南
  • SystemVerilog $cast深度解析:类型安全转换与UVM验证实践
  • Wi-Fi 6 TWT技术详解:从功耗管理到网络性能优化
  • Vim-go插件:在Vim中构建高效Go语言开发环境
  • C#工业自动化:基于插件化架构的Modbus通信系统设计与实现
  • 光猫改桥接模式实战:联通DT741+华为WS5200提升家庭网络性能
  • OpenBSD 不只是服务器系统,它正在改变我对桌面操作系统的看法