参考资料[blind75](Practice (neetcode.io)) ,[代码随想录](代码随想录 (programmercarl.com))
([视频链接](Top K Frequent Elements - Bucket Sort - Leetcode 347 - Python (youtube.com)))
目的 | 代码 | 作用 |
---|---|---|
设置初始列表长度,随给定数组变化 | freq = [[] for i in range(len(nums) + 1)] | 初始化一个包含特定数量空列表的列表 |
目的 | 拆分代码 | 作用 |
---|---|---|
创建范围 | range(len(nums) + 1) |
range 函数的范围是从起始值(包括)到结束值(不包括),并且可以通过指定步长来调整范围中的间隔。本句: 1.创建一个范围,包含从 0 到 len(nums) 的整数。2.共有 len(nums) + 1 个元素,即:[0,len(nums)] 。3.注意:这里的“+1”只是考虑到range函数左闭右开的特性,为了使列表的范围包含边界len(nums)。 range函数默认步长为1,这里没有指定步长。如果想要指定步长为2,则可改为 range(0, len(nums) + 1, 2) |
遍历元素 | for i in range(len(nums) + 1) |
遍历上述范围中的每个元素,用变量 i 表示当前元素。这里的元素即为[0,len(nums)**]**的整数。 |
列表推导式(List Comprehension) | [[] for i in range(len(nums) + 1)] |
对于每个 i ,创建一个空列表 [] ,将这些空列表组成一个新的列表。最终得到一个包含 len(nums) + 1 个空列表的列表。注意:这是处理列表的固定操作,但是这里的子方括号不是固定用法,只是许多操作方式的一种,具体用法如下。 |
代码基本形式 | 作用 |
---|---|
[对元素的处理/转换 for 迭代对象中的元素 in 列表/元组/字符串等可迭代对象 if 可选条件] | 列表推导式是一种简洁的语法结构 用于在一行内创建、转换和过滤列表。 |
功能 | 代码 | 输出 |
---|---|---|
生成平方数列表 | squares = [x**2 for x in range(5)] |
[0, 1, 4, 9, 16] |
筛选偶数 | even_numbers = [x for x in range(10) if x % 2 == 0] |
[0, 2, 4, 6, 8] |
转换为大写 | words = ["apple", "banana", "cherry"] uppercase_words = [word.upper() for word in words] |
['APPLE', 'BANANA', 'CHERRY'] |
生成和为偶数的元组列表 | pairs = [(x, y) for x in range(3) for y in range(3) if (x + y) % 2 == 0] |
[(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)] |
我的思路:解决这个问题,首先需要对数组里的数字出现次数进行统计
- 知识迁移(旧知识):联想到组字谜的题目中,为了统计字符串的字母数量,定义了count[]列表将字母转换为列表嘚索引,每遍历到一个字母就在对应的位置加1,从而实现计数功能。
- 知识迁移(新问题):本题数字天然顺序从0开始,与索引一致。然而字母有限最多26个,而本题数组几乎不限,造成的复杂度很大。
- 解决方法:然后就没有然后了。。
本题思路: 一般的思路是数组中的数字当索引,列表值来统计出现次数,然而本题只需要前K个最频繁的数字,所以可以颠倒过来,让次数当索引,数字填在对应次数的位置上恒威列表的值(其中,列表值的属性为列表,以防有数字出现次数相同)。其中,列表的索引最大值为数组长度(最坏的情况,每个数字都不同),即列表长度最大为数组长度加1(索引从0开始)
题串思路:
- 先利用哈希表计算出每个元素频率
- 215题:数组中的第K个最大元素
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
# 创建一个字典 count 用于记录每个数字出现的次数
count = {}
# 创建一个频率列表 freq,索引 i 对应的列表存储数字出现频率为 i 的数字
freq = [[] for i in range(len(nums) + 1)]
# 计算每个数字的出现次数
for n in nums:
count[n] = 1 + count.get(n, 0)
# 将数字按照出现频率分组存储在 freq 列表中
for n, c in count.items():
freq[c].append(n)
# 从高频率向低频率遍历 freq 列表,将数字加入结果列表 res
res = []
for i in range(len(freq) - 1, 0, -1):
for n in freq[i]:
res.append(n)
# 当结果列表长度达到 k 时,返回结果
if len(res) == k:
return res
# 如果 k 大于等于列表长度,直接返回结果列表
return res