140:套碗游戏的取碗顺序问题(二) | 栈与卡特兰数
今天我们来聊一聊,豆包MarsCode AI刷题中【第140道题:套碗游戏的取碗顺序问题(二)】所涉及到的知识点。
问题描述
小F正在玩一个套碗的游戏,每个碗都有一个编号,从1到n,它们从大到小被套在一根木棍上。小F只能从木棍上取最上面的碗,每次只能取一个。现在你需要计算总共有多少种取碗的顺序。
例如,对于2个碗,取碗的顺序可以是 2 1 或 1 2,这两种顺序都是合法的。而对于3个碗,给定顺序 3 1 2 不可能通过合法操作实现,因此该顺序不可行。
这道题涉及到了两个知识点:1.栈 2.卡特兰数。接下来我们来逐个讲一讲。
1. 栈
栈大家应该都不陌生,它是一种数据结构,遵循 后进先出(LIFO, Last In First Out) 的原则。即,最新加入的元素最先被移除。
1.1 栈的基本特点
-
后进先出(LIFO)
- 栈就像一叠盘子,最后放上去的盘子是第一个被拿走的。
-
操作限制
- 只能在一端进行元素的插入(入栈,Push) 和移除(出栈,Pop) 操作。
-
顶端(Top)
- 栈的操作只能发生在栈的顶部。
1.2 栈的基本操作
-
Push(入栈)
向栈的顶部添加一个元素。
示例代码(Python):stack = [] stack.append(10) # 入栈操作,将10压入栈中 -
Pop(出栈)
从栈的顶部移除一个元素。
示例代码:top_element = stack.pop() # 出栈操作,移除并返回顶部元素 -
Peek(查看栈顶元素)
查看但不移除栈顶元素。
示例代码:top_element = stack[-1] # 查看栈顶元素 -
IsEmpty(判断栈是否为空)
检查栈中是否还有元素。
示例代码:is_empty = len(stack) == 0 # 如果栈为空,则返回True
2. 卡特兰数(Catalan Number)
相较于栈,卡特兰数对一些人来说可能比较陌生,但这道题实际上是卡特兰数的应用。
2.1 什么是卡特兰数?
卡特兰数是一个重要的数学序列,广泛用于组合数学和算法中。它描述了许多问题中的计数结果,例如括号匹配方案、二叉树结构、栈排序、网格路径等。
2.2 对应的序列为
2.3 第 n 项 Hn 的值为
其满足递推关系:
题目解法
因此,这道题可以用递推公式来实现:
def solution(M: int) -> int:
# 初始化卡特兰数的数组
catalan = [0] * (M + 1)
catalan[0] = 1 # C_0 = 1
# 递推计算卡特兰数
for n in range(1, M + 1):
for i in range(n):
catalan[n] += catalan[i] * catalan[n - 1 - i]
return catalan[M]