问题描述
小C来到了一家餐馆,准备点一些菜。
已知该餐馆有 nn 道菜,第 ii 道菜的售价为 wiwi。
小C准备点一些价格相同的菜,但小C不会点单价超过 mm 的菜。
小C想知道,自己最多可以点多少道菜?
测试样例
样例1:
输入:
m = 6, w = [2, 3, 3, 6, 6, 6, 9, 9, 23]
输出:3
样例2:
输入:
m = 4, w = [1, 2, 4, 4, 4]
输出:3
样例3:
输入:
m = 5, w = [5, 5, 5, 5, 6, 7, 8]
输出:4
解题思路
问题理解
小C来到一家餐馆,准备点一些价格相同的菜,但不会点单价超过 m 的菜。我们需要找出小C最多可以点多少道菜。
解题思路
-
过滤菜品:
- 首先,我们需要过滤出价格不超过
m的菜品。
- 首先,我们需要过滤出价格不超过
-
统计出现次数:
- 然后,我们统计每个价格出现的次数。
-
查找最大值:
- 最后,我们查找出现次数最多的价格,并返回该价格的出现次数。
数据结构选择
- 列表:用于存储过滤后的菜品价格。
- Counter:用于统计每个价格出现的次数。
算法步骤
-
过滤菜品:
- 遍历输入列表
w,将价格不超过m的菜品价格添加到一个新的列表中。
- 遍历输入列表
-
统计出现次数:
- 使用
Counter对象统计过滤后的列表中每个价格出现的次数。
- 使用
-
查找最大值:
- 使用
max函数查找出现次数最多的价格,并返回该价格的出现次数。
- 使用
时间复杂度
-
过滤菜品:时间复杂度为
O(n),其中n是输入列表w的长度。 -
统计出现次数:时间复杂度为
O(n),因为Counter对象的构造函数会遍历整个列表。 -
查找最大值:时间复杂度为
O(k),其中k是不同价格的个数,通常k远小于n。因此,总的时间复杂度是
O(n)。
空间复杂度
- 空间复杂度:主要取决于过滤后的列表和
Counter对象的大小,通常也是O(n)。
解题代码
代码详解
导入 Counter 模块:
from collections import Counter
- 从
collections模块中导入Counter类,用于统计列表中每个元素的出现次数。
定义 solution 函数:
def solution(m: int, w: list) -> int:
- 定义一个名为
solution的函数,接受两个参数:m(价格上限)和w(菜品价格列表),并返回一个整数。
创建空列表 list:
list = []
- 创建一个空列表
list,用于存储价格不超过m的菜品。
遍历输入列表 w:
for i in w: if i <= m: list.append(i)
- 遍历输入列表
w中的每个价格i。 - 如果当前价格
i不超过m,则将其添加到列表list中。
检查过滤后的列表是否为空:
if list == []: return 0
- 如果过滤后的列表
list为空,表示没有符合条件的菜品,返回0。
统计每个价格的出现次数:
count = Counter(list)
- 使用
Counter统计列表list中每个价格出现的次数,并将结果存储在count变量中。
返回出现次数最多的价格的出现次数:
return count[max(count.keys(), key=count.get)]
-
- 使用
max函数和key=count.get参数,找到出现次数最多的价格。
- 使用
- 返回该价格的出现次数。
思考总结
在编写这段代码的过程中,我深刻体会到使用 Python 内置工具的便利性。通过 Counter 对象,我们能够轻松地统计每个价格的出现次数,而 max 函数则帮助我们快速找到出现次数最多的价格。这种简洁而高效的方法不仅减少了代码量,还提高了代码的可读性和可维护性。此外,通过过滤和计数,我们能够有效地处理大规模数据,确保算法的性能。总体而言,这段代码的编写过程让我更加熟悉了 Python 的强大功能,也让我对算法设计有了更深的理解。