【Leetcode 692.前K个高频单词】(Python3完整代码)

一、题目描述

给一非空的单词列表,返回前 k 个出现频率最高的单词。

要求:

  1. 频率高的单词排在前面;
  2. 若多个单词频率相同,按字典序升序排列;
  3. 保证答案唯一,且 1 ≤ k ≤ 单词列表中不同单词的数量

示例 1:

输入:words = ["i","love","leetcode","i","love","coding"], k = 2

输出:["i","love"]

解释:"i" 和 "love" 分别出现 2 次,"i" 字典序小于 "love",故排在前。

示例 2:

输入:words = ["the","day","is","sunny","the","the","the","sunny","is","is"], k = 4

输出:["the","is","sunny","day"]

解释:频率排序:the (4) > is (3) > sunny (2) > day (1),
           频率相同无冲突,按顺序返回前 4 个。

二、解法思路:

解法一:哈希表 + 自定义排序

1.思路分析:

  1. 统计频率:用哈希表统计每个单词的出现次数;
  2. 自定义排序:对哈希表的键值对排序,排序规则为:
    1. 优先按频率降序(频率高的在前);
    2. 频率相同时按单词字典序升序(字典序小的在前);
  3. 截取结果:取排序后前 k 个单词作为答案。

2. 完整代码(带详细注释)

class Solution: def topKFrequent(self, words: List[str], k: int) -> List[str]: # 统计每个单词的出现频率 dictword = {} for word in words: # get方法简化计数:存在则取当前值+1,不存在则默认0+1 dictword[word] = dictword.get(word, 0) + 1 # 自定义排序: # key=lambda x: (-x[1], x[0]) # -x[1]:按频率降序(负号实现降序);x[0]:频率相同时按单词字典序升序 dictword_sorted = sorted(dictword.items(), key=lambda x: (-x[1], x[0])) # 3. 截取前k个单词,组装结果列表 res = [] for key, val in dictword_sorted[:k]: res.append(key) return res

3. 代码核心解析

(1)频率统计
        words = ["i","love","leetcode","i","love","coding"]

        遍历后 dictword = {"i":2, "love":2, "leetcode":1, "coding":1}。

(2)自定义排序

sorted(dictword.items(), key=lambda x: (-x[1], x[0]))
    dictword.items():将字典转为元组列表 [("i",2), ("love",2), ("leetcode",1), ("coding",1)];

    key=lambda x: (-x[1], x[0])
            -x[1]:对频率(x [1])取负,实现降序(2 > 1);
            x[0]:频率相同时,按单词(x [0])的字典序升序("i" < "love");

    排序结果:[("i",2), ("love",2), ("coding",1), ("leetcode",1)]。
    (3)截取结果

    取前 k=2 个元组的单词部分,得到 ["i","love"],符合题目要求。

    4. 复杂度分析

    • 时间复杂度:O(nlogn)
      • 统计频率:O(n)(n 为单词列表长度);
      • 排序:O(mlogm)(m 为不同单词的数量,m≤n),是时间瓶颈;
    • 空间复杂度:O(n)
      • 哈希表存储所有不同单词,排序需额外存储元组列表,整体为O(n)。

    5. 优缺点

    • 优点:代码极简、逻辑直观,无需自定义类或掌握堆的复杂用法,新手极易上手;

    缺点:排序需遍历所有不同单词,当 n 极大(如

    10^{6}

    )且 k 极小时(如 k=10),效率低于堆解法。

    解法二:哈希表 + 小顶堆

    1. 思路分析

    针对排序解法的效率问题,用小顶堆优化:仅维护 k 个元素,避免对所有单词排序,核心逻辑:

    1. 哈希表统计频率(同解法一);
    2. 遍历哈希表,将(单词,频率)推入小顶堆,保持堆大小不超过 k
      (超过则弹出 “最小” 元素);
    3. 堆中剩余的 k 个元素是前 k 高频单词,反转后得到最终结果

    2. 完整代码(带详细注释)

    import heapq class Solution: def topKFrequent(self, words: List[str], k: int) -> List[str]: # 统计每个单词的出现频率 mapping = {} for word in words: mapping[word] = mapping.get(word, 0) + 1 # 初始化小顶堆,筛选前k个高频单词 heap = [] for key, val in mapping.items(): # 将自定义Node推入堆,heapq会按__lt__规则排序 heapq.heappush(heap, Node(key, val)) # 保持堆大小为k,超过则弹出“最小”的元素(频率最低/同频率字典序大) if len(heap) > k: heapq.heappop(heap) # 提取堆中元素并调整顺序 res = [] # 弹出堆顶(此时堆内元素是“小→大”,如[love, i]) while len(heap) > 0: temp = heapq.heappop(heap) res.append(temp.key) # 反转后得到“大→小”的正确顺序(如[i, love]) res.reverse() return res # 自定义堆节点类,实现比较逻辑 class Node: def __init__(self, key, val): self.key = key # 单词 self.value = val # 出现频率 # 核心:自定义小于(__lt__)规则,适配小顶堆的排序逻辑 def __lt__(self, other): # 规则1:频率相同 → 字典序大的单词“更小”(优先被弹出) if self.value == other.value: return self.key > other.key # 规则2:频率不同 → 频率小的单词“更小”(优先被弹出) else: return self.value < other.value

    3. 核心解析(关键难点)

    (1)自定义 Node 类的比较规则

            Python 的heapq默认是小顶堆,需重写__lt__方法(less than)适配题目规则:

    def __lt__(self, other): return self.key>other.key if self.value==other.value else self.value<other.value
    频率相同:字典序大的单词(如 "love")被判定为 “更小”,优先弹出;频率不同:频率小的单词(如 "coding")被判定为 “更小”,优先弹出。
    (2)堆筛选过程(以示例 1 为例)
    • 推入 ("i",2) → 堆:[Node (i,2)](大小 1 ≤2);
    • 推入 ("love",2) → 堆:[Node (love,2), Node (i,2)](大小 2 ≤2);
    • 推入 ("leetcode",1) → 堆大小 3>2 → 弹出堆顶(Node (leetcode,1));
    • 推入 ("coding",1) → 堆大小 3>2 → 弹出堆顶(Node (coding,1));
    • 最终堆内元素:[Node(love,2), Node(i,2)],弹出后反转得到["i","love"]。

    4. 复杂度分析

    • 时间复杂度:O(nlogk)
      • 统计频率:O(n);
      • 堆操作:每次 push/pop 为O(logk),最多执行m次(m≤n),整体为O(mlogk);
      • 当k≪n时,O(nlogk)≪O(nlogn),效率优势明显;
    • 空间复杂度:O(n)(哈希表 + 堆,堆仅占O(k))。

    5. 优缺点

    • 优点:时间效率更高,适合大数据量、小 k 的场景;
    • 缺点:代码稍复杂,需理解堆的特性和自定义比较规则。

    Read more

    2026年最新AI大模型学习路线(超详细,小白/程序员必收藏)从入门到精通!

    2026年最新AI大模型学习路线(超详细,小白/程序员必收藏)从入门到精通!

    当下AI大模型在人工智能领域的热度持续攀升,已然成为技术圈的核心风口,不仅吸引了大量行业从业者深耕,更有无数编程小白、转行人士想要入门掘金。但很多人面对繁杂的技术资料无从下手,不知道该从哪里开始、按什么顺序学习,踩了不少弯路。 今天就给大家整理了一份2026年最新、最系统的AI大模型学习路线,从0基础入门到精通实战,配套全套学习资源,不管你是纯小白还是有一定基础的程序员,跟着学就能少走弯路、快速上手,建议收藏备用,避免后续找不到! 1、大模型学习路线 2、从0到进阶大模型学习视频教程 从入门到进阶这里都有,跟着老师学习事半功倍。 3、 入门必看大模型学习书籍&文档.pdf(书面上的技术书籍确实太多了,这些是我精选出来的,还有很多不在图里) 4、 AI大模型最新行业报告 2026最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。 5、面试试题/经验 【大厂 AI 岗位面经分享(107 道)】 【AI

    By Ne0inhk
    医疗编程AI技能树与培训技能树报告(国内外一流大学医疗AI相关专业分析2025版,上)

    医疗编程AI技能树与培训技能树报告(国内外一流大学医疗AI相关专业分析2025版,上)

    引言:医疗AI编程的时代背景与技能体系框架 全球医疗AI市场正以爆发式速度增长,预计2025年市场规模将达到1100亿美元,年复合增长率(CAGR)高达38%[1]。这一增长背后是AI技术在临床场景的深度渗透:AI辅助肺结节检测敏感度已突破95%,某知名医院利用大型语言模型(LLM)开发的智能诊断系统将误诊率降低15%,瑞金医院通过AI技术使病理诊断效率提升百倍[2][3][4]。当手术机

    By Ne0inhk
    【保姆级教程】小白也能搞定!手把手教你部署AI小说生成器

    【保姆级教程】小白也能搞定!手把手教你部署AI小说生成器

    目录 一、 磨刀不误砍柴工:环境准备 二、 第一次安装:给代码安个家 第一步:把项目“搬”回家 第二步:造一个专属“房间” 第三步:安装依赖 第四步:点火启动 三、 关机重启后:如何再次开启? 四、 关键一步:配置“大脑”(API接口) 五、开始你的创作 六、写在最后:为什么推荐用蓝耘做“大脑”? 在这个AI辅助创作爆发的时代,拥有一款属于自己的本地AI写作工具,无疑是许多文字工作者的梦想。最近拿到一份AI小说生成器的部署文档,虽然功能强大,但对于非技术出身的朋友来说,那些代码和命令行多少有些“劝退”。 别担心,今天我们就把这份“天书”翻译成“人话”,手把手带你从零开始,搭建属于你的AI创作助手。无论你是第一次安装,还是关机后不知道怎么重启,这篇教程都能帮你搞定。

    By Ne0inhk
    【AI辅助编程】【Claude Code】----秒杀 Cursor!Claude Code 保姆级教程,从安装到实战全过程,一篇文章给你透

    【AI辅助编程】【Claude Code】----秒杀 Cursor!Claude Code 保姆级教程,从安装到实战全过程,一篇文章给你透

    文章目录 * 前言 * 一、基础概念解析, * 1.1、什么是Claude Code? * 1.2、Claude Code能干嘛? * 二、安装 Claude Code * 2.1、(方式一)基于node.js环境 * 2.2、(方式二)不依赖node.js环境,原生版(推荐) * 三、配置 * 3.1配置大模型端点和密钥 * 1.注册账号 (通过上面提供的连接注册) * 2.获取API Key * 3.配置cluade code 环境变量 * 4.测试配置: * 5.切换模型(非必要,可跳过) * 6.查看token用量

    By Ne0inhk