问题描述
小C来到一家餐馆,餐馆中有 n 道菜,每道菜的价格为 w[i]。小C打算选择一些价格相同的菜肴,但单价不能超过 m。
问题是:小C最多能点多少道价格相同且不超过 m 的菜?
解题思路
本题可以通过哈希表(字典)或排序+计数的方法解决。下面是详细的解题步骤。
解题步骤
-
过滤菜肴价格:
- 首先,我们需要过滤掉所有价格大于
m的菜肴,因为小C不会选择单价超过m的菜。
- 首先,我们需要过滤掉所有价格大于
-
统计每种价格的出现次数:
- 对于每个有效的菜肴价格(即不超过
m),我们统计其出现的次数。可以使用字典(哈希表)来进行统计,键是菜肴的价格,值是该价格的出现次数。
- 对于每个有效的菜肴价格(即不超过
-
获取最大出现次数:
- 从统计的价格出现次数中,找出最大值,这个值即是小C最多能选择的菜肴数量。
实现代码(Python)
python
复制代码
def max_dishes(m, w):
# 过滤价格数组,保留所有小于等于 m 的菜
filtered_w = [price for price in w if price <= m]
# 使用字典统计每个价格的数量
price_count = {}
for price in filtered_w:
if price in price_count:
price_count[price] += 1
else:
price_count[price] = 1
# 返回出现次数最多的价格的菜肴数量
return max(price_count.values(), default=0)
# 测试用例
m = 6
w = [2, 3, 3, 6, 6, 6, 9, 9, 23]
print(max_dishes(m, w)) # 输出: 3
代码解析
-
过滤菜肴价格:
- 我们使用列表推导式从价格数组
w中过滤掉所有大于m的菜肴价格,得到一个新的数组filtered_w。
- 我们使用列表推导式从价格数组
-
统计每种价格的出现次数:
- 使用一个字典
price_count来统计每个价格出现的次数。对于每个价格price,如果它已经在字典中出现过,则将其计数加 1;否则,将其加入字典并初始化计数为 1。
- 使用一个字典
-
返回最大出现次数:
- 使用
max(price_count.values())来获取字典中所有出现次数的最大值,即小C最多能选择的相同价格的菜肴数量。如果字典为空(即所有菜肴的价格都大于m),则返回0。
- 使用
时间复杂度分析
- 过滤价格数组:过滤操作是线性的,时间复杂度为
O(n),其中n是菜肴的数量。 - 统计价格频率:遍历过滤后的菜肴数组并更新字典,每个操作的时间复杂度为
O(1),总的时间复杂度为O(n)。 - 最大值计算:从字典中获取最大值的时间复杂度是
O(k),其中k是不超过m的不同价格种类数。由于k至多为n,因此这个操作的时间复杂度是O(n)。
综上,整体时间复杂度为 O(n)。
空间复杂度分析
- 过滤后的数组:最多包含
n个元素,因此空间复杂度为O(n)。 - 字典存储价格频率:字典的大小为不同价格的种类数
k,最坏情况下k也是n,因此空间复杂度为O(n)。
综上,整体空间复杂度为 O(n)。
示例分析
示例 1:
- 输入:
m = 6, w = [2, 3, 3, 6, 6, 6, 9, 9, 23] - 过滤掉价格大于
6的菜肴,得到filtered_w = [2, 3, 3, 6, 6, 6]。 - 统计每种价格出现的次数:
{2: 1, 3: 2, 6: 3}。 - 结果:出现次数最多的价格是
6,出现次数为3。 - 输出:
3
示例 2:
- 输入:
m = 4, w = [1, 2, 4, 4, 4] - 过滤掉价格大于
4的菜肴,得到filtered_w = [1, 2, 4, 4, 4]。 - 统计每种价格出现的次数:
{1: 1, 2: 1, 4: 3}。 - 结果:出现次数最多的价格是
4,出现次数为3。 - 输出:
3
示例 3:
- 输入:
m = 5, w = [5, 5, 5, 5, 6, 7, 8] - 过滤掉价格大于
5的菜肴,得到filtered_w = [5, 5, 5, 5]。 - 统计每种价格出现的次数:
{5: 4}。 - 结果:出现次数最多的价格是
5,出现次数为4。 - 输出:
4
总结
本题通过利用字典统计每种价格的出现次数,然后找出出现次数最多的价格,解决了小C能点多少道菜的问题。时间复杂度为 O(n),适合处理较大规模的输入。