小C的点菜问题 | 豆包MarsCode AI 刷题

44 阅读3分钟

题目分析

小C来到餐馆,想要点一些菜,满足以下条件:

  1. 选择价格相同的菜。
  2. 不会选择单价超过 m 的菜。
  3. 求小C最多可以点多少道菜。

输入:

  • 一个整数 m,表示小C接受的最大单价。
  • 一个整数列表 w,表示每道菜的售价。

输出:

  • 一个整数,表示小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


题目思路

我们需要解决以下几个关键问题:

  1. 统计每种售价的出现次数:我们需要知道每种价格的菜有多少道。
  2. 过滤条件:只考虑价格不超过 m 的菜。
  3. 找到最大值:从满足条件的价格中,选择出现次数最多的菜。

实现步骤:

  1. 统计每个售价的频率:可以用 Python 的 collections.Counter 来统计。
  2. 过滤价格不超过 m 的菜:通过条件过滤筛选掉价格超过 m 的选项。
  3. 取出现次数的最大值:从符合条件的统计结果中找到最大值即可。

代码实现

完整代码

from collections import Counter

def max_dishes(m, w):
    # 统计每种售价的频率
    count = Counter(w)
    # 筛选价格不超过 m 的售价及其对应数量,并找到最大数量
    return max((cnt for price, cnt in count.items() if price <= m), default=0)

# 测试样例
print(max_dishes(6, [2, 3, 3, 6, 6, 6, 9, 9, 23]))  # 输出:3
print(max_dishes(4, [1, 2, 4, 4, 4]))               # 输出:3
print(max_dishes(5, [5, 5, 5, 5, 6, 7, 8]))         # 输出:4

代码讲解

Step 1: 导入库

from collections import Counter

Countercollections 模块中的一个工具,用于统计可迭代对象中每个元素的出现次数。

Step 2: 使用 Counter 统计频率

count = Counter(w)

示例:
w = [2, 3, 3, 6, 6, 6, 9, 9, 23] 时,Counter(w) 的结果为:

{2: 1, 3: 2, 6: 3, 9: 2, 23: 1}

Step 3: 筛选符合条件的菜

(cnt for price, cnt in count.items() if price <= m)

这是一个生成器表达式,逐一筛选价格不超过 m 的菜:

  • price <= m 用于过滤价格超过 m 的菜。
  • 仅返回符合条件的数量 cnt

对于 m = 6,筛选后的结果是:[1, 2, 3]

Step 4: 找到最大值

max((cnt for price, cnt in count.items() if price <= m), default=0)
  • max() 函数从生成器表达式中找到最大值。
  • 如果所有菜的价格都超过 m,则生成器表达式为空,返回 default=0

Step 5: 返回结果

最终返回符合条件的菜中最多的数量。


复杂度分析

  1. 时间复杂度
  • 构建 Counter 需要遍历列表一次,时间复杂度为 O(n)O(n)
  • 过滤和取最大值操作也是 O(n)O(n)
    总时间复杂度:O(n)O(n)
  1. 空间复杂度
  • Counter 的空间复杂度取决于价格的种类数量,最坏情况下为 O(k)O(k),其中 kk 是价格种类数。
    总空间复杂度:O(k)O(k)

总结

这段代码通过 Python 的语法糖和内置工具实现了简洁高效的解法,具有以下特点:

  • 代码简洁:仅用一行生成器表达式完成筛选和求最大值。
  • 易读性强:逻辑清晰,模块化。
  • 性能优良:线性时间复杂度适合大规模数据处理。

如果对 Python 不熟悉,也可以进一步拆分步骤便于理解,但以上实现是优化后的推荐方案。