问题描述
小F正在玩一个套碗的游戏,每个碗都有一个编号,从1到n,它们从大到小被套在一根木棍上。小F只能从木棍上取最上面的碗,每次只能取一个。现在你需要判断给定的取碗顺序是否可行。如果可行,那么返回1,否则返回0。
例如,对于2个碗,取碗的顺序可以是 2 1 或 1 2,这两种顺序都是合法的。而对于3个碗,给定顺序 3 1 2 不可能通过合法操作实现,因此该顺序不可行。
问题理解
你有一个从大到小排列的碗堆,编号从1到n。你只能从最上面取碗。给定一个取碗的顺序,你需要判断这个顺序是否可以通过合法的操作实现。
解题思路
-
模拟取碗过程:
- 你可以使用一个栈来模拟取碗的过程。栈的特点是后进先出(LIFO),这与取碗的规则相符。
- 初始时,所有碗都在木棍上,编号从1到n。
-
逐步取碗:
- 从木棍上取碗,如果当前碗的编号与目标顺序中的下一个编号匹配,则直接取下。
- 如果不匹配,则将木棍上的碗放入栈中,直到找到匹配的碗。
- 如果栈顶的碗与目标顺序中的下一个编号匹配,则从栈中取碗。
-
判断可行性:
- 如果在某个时刻,木棍和栈中都没有与目标顺序匹配的碗,则说明该顺序不可行。
数据结构选择
- 栈:用于模拟取碗的过程。
- 指针或索引:用于跟踪当前需要取的碗的编号。
算法步骤
-
初始化一个空栈。
-
使用一个指针或索引
i来跟踪目标顺序中的当前位置。 -
从1到n遍历每个碗:
- 如果当前碗的编号与目标顺序中的下一个编号匹配,则直接取下。
- 如果不匹配,则将当前碗放入栈中。
- 检查栈顶的碗是否与目标顺序中的下一个编号匹配,如果匹配则从栈中取碗。
-
如果遍历结束后,栈为空且所有碗都按顺序取下,则返回1,否则返回0。
实战
def solution(M: int, a: list) -> int: stack = [] i = 0 # 用于跟踪目标顺序中的当前位置 for num in range(1, M + 1): # 如果当前碗与目标顺序中的下一个编号匹配,直接取下 if num == a[i]: i += 1 else: # 否则将当前碗放入栈中 stack.append(num)
# 检查栈顶的碗是否与目标顺序中的下一个编号匹配
while stack and stack[-1] == a[i]:
stack.pop()
i += 1
# 如果栈为空且所有碗都按顺序取下,则返回1,否则返回0
return 1 if not stack else 0