解题思路:点菜问题
问题描述
小C需要点一些价格相同的菜,但在点菜时受到以下限制:
- 小C不会点价格超过
m的菜。 - 小C想知道最多可以点多少道价格相同的菜。
这意味着我们需要找到价格不超过 m 的菜品中,某一价格出现的最大次数。例如,如果菜品价格为 [5, 10, 5, 20],而 m = 10,那么最多可以点两道价格为 5 的菜。
解题思路
为了解决这一问题,可以通过以下几个步骤实现:
1. 过滤符合条件的菜品
首先,剔除价格超过 m 的菜品。使用 Python 的列表推导式可以高效地完成这一步骤,生成一个新的列表仅包含符合条件的菜品。
例如,对于 w = [5, 10, 5, 20] 和 m = 10,过滤后的结果为 [5, 10, 5]。这一步的目的是简化后续的统计工作,仅关注符合预算的菜品。
代码实现:
filtered_prices = [price for price in w if price <= m]
2. 统计每种价格的菜品数量
接下来,我们需要统计每种价格出现的次数。这一步可以使用 Python 的 collections.Counter,它能够快速统计每个元素的出现频率,并返回一个字典结构,其中键是价格,值是出现的次数。
对于输入 [5, 10, 5],Counter 的输出为:
from collections import Counter
price_count = Counter(filtered_prices)
3. 寻找最大值
从统计结果中找到菜品价格出现的最大次数,即为我们最终的结果。如果没有符合条件的菜品,则直接返回 0。可以通过 max() 函数完成这一步操作,同时提供一个默认值避免异常。
对于统计结果 {5: 2, 10: 1},最大值为 2,表示最多可以点两道价格为 5 的菜。
代码实现:max_count = max(price_count.values(), default=0)
完整算法实现
以下是完整的 Python 实现: from collections import Counter
def solution(m: int, w: list) -> int: # 过滤掉超过 m 的菜品 filtered_prices = [price for price in w if price <= m]
# 统计每种价格出现的次数
price_count = Counter(filtered_prices)
# 返回最大出现次数
return max(price_count.values(), default=0)
实践案例分析
示例 1
-
输入:
m = 10, w = [5, 10, 5, 20] -
过程:
- 过滤:
[5, 10, 5] - 统计:
{5: 2, 10: 1} - 最大值:
2
- 过滤:
-
输出:
2
示例 2
-
输入:
m = 15, w = [5, 10, 15, 20, 15] -
过程:
- 过滤:
[5, 10, 15, 15] - 统计:
{5: 1, 10: 1, 15: 2} - 最大值:
2
- 过滤:
-
输出:
2
示例 3
-
输入:
m = 8, w = [9, 10, 11] -
过程:
- 过滤:
[] - 统计:
{} - 最大值:
0
- 过滤:
-
输出:
0
时间和空间复杂度分析
时间复杂度
-
过滤步骤:
- 遍历所有菜品,复杂度为 O(n)O(n)O(n),其中 nnn 是菜品的数量。
-
统计步骤:
- 遍历过滤后的菜品,复杂度为 O(k)O(k)O(k),其中 kkk 是过滤后菜品的数量。
-
寻找最大值:
- 遍历统计结果的键值对,复杂度为 O(p)O(p)O(p),其中 ppp 是价格种类的数量。
总时间复杂度为 O(n+k+p)O(n + k + p)O(n+k+p),近似为 O(n)O(n)O(n)。
空间复杂度
-
存储过滤后的菜品:
- 空间复杂度为 O(k)O(k)O(k)。
-
存储统计结果:
- 空间复杂度为 O(p)O(p)O(p)。
总空间复杂度为 O(k+p)O(k + p)O(k+p)。
优势与总结
使用该算法的优势
-
高效过滤和统计:
- 通过列表推导式和
Counter模块,快速完成菜品过滤和统计,提升了算法效率。
- 通过列表推导式和
-
简单易懂的代码结构:
- 算法逻辑分为过滤、统计和取最大值三步,每一步都独立清晰,便于维护和调试。
总结
通过本算法,我们能够快速找到符合预算的菜品中,某一价格出现的最大次数。这不仅解决了点菜问题,也为解决类似“最大频率统计”的问题提供了通用模板。