“154. 小C点菜问题”题解 | 豆包MarsCode AI刷题

30 阅读3分钟

该题目的题目描述如下:

小C来到了一家餐馆,准备点一些菜。 已知该餐馆有 nn 道菜,第 ii 道菜的售价为 wi。 小C准备点一些价格相同的菜,但小C不会点单价超过 m 的菜。 小C想知道,自己最多可以点多少道菜?

题目多给的输入输出样例如下所示:

输入:m = 6, w = [2, 3, 3, 6, 6, 6, 9, 9, 23] 输出:3
输入:m = 4, w = [1, 2, 4, 4, 4] 输出:3
输入:m = 5, w = [5, 5, 5, 5, 6, 7, 8] 输出:4

通过简单分析题目,我们可以得知,题目要求我们帮助小C在餐馆中选择尽可能多的价格相同且不超过某个最大单价 m 的菜肴。给定一个菜品价格列表,目标是找出在价格不超过 m 的范围内,小C最多可以点几道价格相同的菜。

首先,菜品的价格列表 w[] 中的每个元素代表一种菜的价格。我们需要根据菜品的价格进行统计。题目明确指出小C只会选择单价不超过 m 的菜肴,这就限制了我们只能关注那些价格不超过 m 的菜品。最终目标是找出在价格不超过 m 的范围内,最多可以点多少道价格相同的菜。换句话说,我们要计算每个价格出现的次数,找到出现次数最多的价格,且该价格不大于 m

我的第一版代码如下:

def solution(m: int, w: list) -> int:
    num_of_food = {}
    memo_max = 0
    for i in w:
        if i > m:
            continue
        if i not in num_of_food.keys():
            num_of_food[i] = 0
        num_of_food[i] += 1
    for j in num_of_food.keys():
        if num_of_food[j] > memo_max:
            memo_max = num_of_food[j]
    return memo_max

上述代码的思路大致如下:

  1. 使用字典统计频次:首先,代码使用了字典 num_of_food 来统计价格不超过 m 的菜品出现的次数,这是一个正确的做法。对于每一个菜品价格 i,如果它不超过 m,就将其加入字典,并更新它的出现次数。
  2. 跳过超过最大价格的菜:你使用了 if i > m: continue 来跳过那些价格超过 m 的菜品,这也是一种有效的方式来筛选符合条件的菜品。
  3. 获取最大频次:接下来,代码遍历字典的键 num_of_food.keys(),并找到出现次数最多的价格,更新 memo_max
  4. 返回结果:最后返回最大频次 memo_max

而对于这一版代码,其实还是有相当大的优化空间的,例如:

  •  keys() 调用:字典的 for 循环可以直接遍历字典的键,而不需要显式地调用 .keys()。因为在 Python 中,直接遍历字典会自动遍历其键,这样可以简化代码。
  • in 操作检查:代码使用 if i not in num_of_food.keys(): 来检查字典中是否已经存在某个价格。这种方法效率较低,因为它在每次检查时都需要遍历字典的键。一个更高效的做法是直接使用 num_of_food.get(i, 0),这样可以避免显式的 in 操作,并且在键不存在时直接返回默认值 0

(具体改进代码这里不再展示)