前言
超市里的货物架调整在青训营X豆包MarsCode刷题打卡中分类为贪心算法、中级难度的问题。
首先,什么是贪心算法呢?
第一次接触贪心算法是在我的算法设计课上,贪心算法(greedy algorithm)又称贪婪算法
是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。
而贪心算法有两个性质
- 贪心选择性质
所求问题的最优解,可以通过一系列局部最优的选择(即贪心选择)来达到。
- 最优子结构
所求问题的最优解包含所有子问题的最优解。
贪心算法可以解决的问题
求解活动安排、构建哈夫曼树、背包问题、最优装载问题等等。
问题描述
在一个超市里,有一个包含n个格子的货物架,每个格子中放有一种商品,商品用小写字母 a 到 z 表示。当顾客进入超市时,他们会依次从第一个格子查找到第n个格子,寻找自己想要购买的商品。如果在某个格子中找到该商品,顾客就会购买它并离开;如果中途遇到一个空格子,或查找完所有格子还没有找到想要的商品,顾客也会离开。
作为超市管理员,你可以在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。当第一个顾客进入后,商品位置不能再调整。你需要计算在最优调整下,最多可以卖出多少件商品。输入变量说明:
n:货物架的格子数m:顾客想要购买的商品种类数s:货物架上商品的初始顺序c:顾客想要购买的商品种类
测试样例
样例1:
输入:n = 3 ,m = 4 ,s = "abc" ,c = "abcd"
输出:3
样例2:
输入:n = 4 ,m = 2 ,s = "abbc" ,c = "bb"
输出:2
样例3:
输入:n = 5 ,m = 4 ,s = "bcdea" ,c = "abcd"
输出:4
对问题的理解
需要在一个超市的货物架上重新排列商品,以便在第一个顾客到来时,能够尽可能多地卖出商品。每个顾客只会购买他们想要的商品中的一种,并且一旦找到就会离开。若没有找到,或看到的是空盒子顾客也会离开。
确定数据结构
- 需求统计:首先,我们需要统计每个顾客想要购买的商品种类及其数量。可以使用
Counter(计数器,一种特殊的字典)来实现这一点。 - 商品排序:我们需要根据顾客的需求量对商品进行排序。需求量大的商品应该放在前面,以便顾客能够更快地找到并购买。
算法步骤
- 统计商品需求:使用
Counter统计顾客想要购买的每种商品的数量。 - 商品排序:根据需求量迅速对商品进行排序,保证需求量大的商品在前,需求量小的商品在后。
- 计算最大销售量:遍历排序后的商品,依次检查每个商品是否还有需求,如果有则增加销售量,并减少该商品的需求量。每卖出一件商品,相应减少一个它的需求量。
通过上述步骤可以得到一个解决问题的简单架构。
问题解答
def solution(n: int, m: int, s: str, c: str) -> int:
# 统计顾客想要购买的每种商品的数量
from collections import Counter
demand = Counter(c)
# 将商品按需求量从大到小排序
sorted_items = sorted(s, key=lambda x: demand[x], reverse=True)
# 将排序后的商品重新组合成一个新的顺序
new_order = ''.join(sorted_items)
# 计算最多可以售出多少件商品
max_sales = 0
for item in new_order:
if demand[item] > 0:
max_sales += 1
demand[item] -= 1
return max_sales
if __name__ == '__main__':
print(solution(3, 4, "abc", "abcd") == 3)
print(solution(4, 2, "abbc", "bb") == 2)
print(solution(5, 4, "bcdea", "abcd") == 4)
解决此问题思路比较重要,在学习编程的过程中,我认为各类算法结构尤其重要。
当看到一个实际问题时,我们首先应该确定该使用什么算法,其次确定所使用的数据结构,主要框架确定好了以后,我们可以使用书写流程图或者NS图来确定编程步骤,最终实操写出最终代码。
本人编程菜鸟,若有不对之处,请在下方留言。