题目描述
思路解析动画文字版
下面 15 步动画会按主解代码推进,而不是泛泛讲题型。
1. 读输入:输入 6 个单词,k = 2,目标是返回出现次数最多的前 2 个单词;频率相同时按字典序升序。
2. 建频率表:先建一个空的频率表 cnt,准备从左到右扫描每个单词,把它的出现次数加 1。
3. 计数 i:下标 0 的单词是 i,频率表里没有 i,记为 1,得到 cnt = {i:1}。
4. 计数 love:下标 1 的单词是 love,第一次出现记为 1,得到 cnt = {i:1, love:1}。
5. 计数 leetcode:下标 2 的单词是 leetcode,第一次出现记为 1,得到 cnt = {i:1, love:1, leetcode:1}。
6. 再遇 i:下标 3 又是 i,已存在则在原值上加 1:1 + 1 = 2,i 的频率升到 2。
7. 再遇 love:下标 4 又是 love,频率从 1 加到 2,现在 i 和 love 都出现了 2 次。
8. 计数 coding:下标 5 的单词是 coding,第一次出现记为 1。6 个单词全部扫完,计数完成。
9. 取出不同单词:去重后得到 4 个不同单词:i、love、leetcode、coding,频率分别是 2、2、1、1,下面对它们排序。
10. 排序规则:排序键是 (-cnt[w], w):先按频率从高到低;频率相同再按单词字典序从小到大。
11. 高频组在前:先按频率分两组:i、love 频率为 2 排在前面(紫框),leetcode、coding 频率为 1 排在后面。
12. 频率 2 组内排序:i 和 love 频率都是 2,按字典序比较,i 小于 love,所以这一组顺序是 i、love。
13. 频率 1 组内排序:leetcode 和 coding 频率都是 1,比字典序 coding 小于 leetcode,所以这一组排成 coding、leetcode。
14. 排序结果:整体排序完成:i(2)、love(2)、coding(1)、leetcode(1),频率降序、同频字典序升序。
15. 取前 k 个返回:取排序后的前 k=2 个单词(标绿),返回 ["i","love"],即出现最多的前两个单词。
记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
参考代码
from collections import Counterclass Solution: def topKFrequent(self, words, k): cnt = Counter(words) return sorted(cnt.keys(), key=lambda w: (-cnt[w], w))[:k]复杂度
- 时间复杂度:O(n + m log m),m 为不同单词数
- 空间复杂度:O(m),频率表
易错点
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
合并 K 个升序链表
LeetCode 23 · 困难 · 沿着 堆套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题