AI的刷题笔记04
题目描述:套碗游戏的取碗顺序问题
小F正在玩一个套碗的游戏,每个碗都有一个编号,从1到n,它们从大到小被套在一根木棍上。小F只能从木棍上取最上面的碗,每次只能取一个。现在你需要判断给定的取碗顺序是否可行。如果可行,那么返回1,否则返回0. 例如,对于2个碗,取碗的顺序可以是2、1或1、2,这两种顺序都是合法的。而对于3个碗,给定顺序3、1、2不可能通过合法操作实现,因此该顺序不可行。
样例1
输入:M=2,a=[1,2] 输出:1
解题核心思路
将其模拟为一个栈的操作问题。我们可以使用栈来模拟从木棍上取碗的操作,检查给定的顺序是否可行。
题目分析
- 小F有一根木棍,木棍上套着
M个碗,编号从1到M。这些碗按照编号从小到大依次套在木棍上,比如编号1的碗最外面,编号M的碗最里面。 - 他想按照一个给定的顺序
a把碗取下来。每次只能从木棍的最外层(栈顶)取碗。 - 如果顺序
a不可能通过合法的取碗操作实现,就返回0;如果可以,则返回1。
解题步骤
模拟取碗的过程,加入一个栈的概念。这个栈用来表示木棍上目前剩下的碗。栈的规则是 后进先出,也就是说,最上面的碗(栈顶)必须先取。符合题目所讲述的要求
准备阶段:定义
- 一个栈
stack用来模拟木棍上当前剩余的碗。 - 一个变量
current表示下一个将要放到木棍上的碗编号,初始值是1,因为碗是从1开始放的。
模拟阶段:判断
- 遍历给定的顺序
a,逐个看要取的碗编号。 - 如果当前栈的最上面不是需要的碗,就从编号为
current的碗开始,把碗依次放到木棍(栈)上,直到找到需要的碗。 - 如果找到需要的碗,就从栈顶取出来。
- 如果放到最后都找不到需要的碗,说明顺序不可能,返回
0。
结束阶段:结果
- 如果整个顺序都满足条件,所有碗都被成功取走,返回
1。
最终代码
def solution(M, a):
stack = [] # 用于模拟木棍上的碗
current = 1 # 当前应该放到木棍上的碗编号
for num in a:
# 将需要的碗逐个放到栈中,直到栈顶是当前需要的碗
while current <= M and (not stack or stack[-1] != num):
stack.append(current)
current += 1
# 如果栈顶不是当前需要的碗,则顺序不可能
if not stack or stack[-1] != num:
return 0
# 否则从栈顶取出碗
stack.pop()
# 如果所有碗都按顺序取完,返回 1
return 1
代码解释
样例1:M=2,a=[1,2]
- 初始栈为空,
current = 1。 - 取第一个碗:
stack = [],将1放入栈中,stack = [1]。- 栈顶是
1,取出1,stack = []。
- 取第二个碗:
stack = [],将2放入栈中,stack = [2]。- 栈顶是
2,取出2,stack = []。
- 所有碗按顺序取完,返回
1。
样例2:M=3,a=[3,1,2]
- 栈
stack一开始是空的,current = 1。 - 现在栈顶没有任何碗,所以从
current = 1开始,把碗1放到栈里,栈变成[1]。- 再放碗
2,栈变成[1, 2]。 - 再放碗
3,栈变成[1, 2, 3]。
- 再放碗
- 栈顶是碗
3,正好是需要的,把它从栈里取走,栈变成[1, 2]。 - 现在栈顶是碗
2,但我们需要的是碗1。这里就出问题了! - 因为碗
1被压在碗2的下面,我们没办法跳过碗2直接取碗1,所以这时候顺序就不合法了。 - 返回
0,说明这组顺序不可行。