问题描述
在一个超市里,有一个包含 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
思路
这个问题是中等难度题,问题看着很复杂,但实际上经过分析以后发现,因为c是可见的,因此我们安排s的位置的时候就相当于开卷作答。分析发现,如果s里面有对应的商品的话,始终按照顾客来的顺序(c中字符出现的顺序)时,能够卖出最多的商品,并且一定能卖出所有拥有的商品。 因此把题目进行究极化简:其实就是看s里面有多少对应的c里面的字符!
代码
这里提供2种代码,一种是字符串处理,一种是用列表处理。
# 方法1:字符串处理
def solution(n: int, m: int, s: str, c: str) -> int:
ans = 0
for good in c:
if good in s:
ans += 1
# 去掉s里面一个good
pos = s.find(good)
s = s[0:pos] + s[pos+1:] #字符串的删除
return ans
# 方法2:转化成列表,删除方便
def solution2(n: int, m: int, s: str, c: str) -> int:
new_shelf = list(s)
# 计算最多可以卖出多少件商品
sold = 0
for item in c:
if item in new_shelf:
sold += 1
new_shelf.remove(item) # 列表的删除
return sold
以下是对这段代码的清晰、简洁的解释:
方法1:字符串处理
def solution(n: int, m: int, s: str, c: str) -> int:
ans = 0
for good in c:
if good in s:
ans += 1
# 去掉s里面一个good
pos = s.find(good)
s = s[0:pos] + s[pos+1:] # 字符串的删除
return ans
解释:
- 参数说明:
n和m是整数,s是一个字符串,表示货架上的商品列表,c是另一个字符串,表示可以销售的商品。 - 初始化:
ans用于记录成功销售的商品数量,初始值为0。 - 遍历销售商品列表:对于字符串
c中的每个商品good:- 检查
good是否在s中。 - 如果存在,
ans增加1。 - 找到
good在s中的位置pos,然后通过切片将该商品从s中删除。
- 检查
- 返回结果:返回成功销售的商品总数
ans。
方法2:转化成列表,删除方便
def solution2(n: int, m: int, s: str, c: str) -> int:
new_shelf = list(s)
# 计算最多可以卖出多少件商品
sold = 0
for item in c:
if item in new_shelf:
sold += 1
new_shelf.remove(item) # 列表的删除
return sold
解释:
- 参数说明:与方法1相同。
- 初始化:将字符串
s转换为列表new_shelf,方便删除元素。 - 遍历销售商品列表:对于字符串
c中的每个商品item:- 检查
item是否在new_shelf中。 - 如果存在,
sold增加1,并直接从new_shelf中删除该商品。
- 检查
- 返回结果:返回成功销售的商品总数
sold。
总结
两种方法都用于计算能从货架 s 中销售的商品数量,区别在于:
- 方法1 使用字符串操作,通过切片删除元素,效率较低。
- 方法2 将字符串转为列表,使用
remove方法更方便高效地删除元素。