刷题相关知识一【栈与卡特兰数】| 豆包MarsCode AI刷题

112 阅读2分钟

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 栈的基本特点
  1. 后进先出(LIFO)

    • 栈就像一叠盘子,最后放上去的盘子是第一个被拿走的。
  2. 操作限制

    • 只能在一端进行元素的插入(入栈,Push)移除(出栈,Pop) 操作。
  3. 顶端(Top)

    • 栈的操作只能发生在栈的顶部。
1.2 栈的基本操作
  1. Push(入栈)
    向栈的顶部添加一个元素。
    示例代码(Python):

    stack = []
    stack.append(10)  # 入栈操作,将10压入栈中
    
  2. Pop(出栈)
    从栈的顶部移除一个元素。
    示例代码:

    top_element = stack.pop()  # 出栈操作,移除并返回顶部元素
    
  3. Peek(查看栈顶元素)
    查看但不移除栈顶元素。
    示例代码:

    top_element = stack[-1]  # 查看栈顶元素
    
  4. IsEmpty(判断栈是否为空)
    检查栈中是否还有元素。
    示例代码:

    is_empty = len(stack) == 0  # 如果栈为空,则返回True
    

2. 卡特兰数(Catalan Number)

相较于栈,卡特兰数对一些人来说可能比较陌生,但这道题实际上是卡特兰数的应用。

2.1 什么是卡特兰数?

卡特兰数是一个重要的数学序列,广泛用于组合数学和算法中。它描述了许多问题中的计数结果,例如括号匹配方案、二叉树结构、栈排序、网格路径等。

2.2 对应的序列为

卡特兰序列.png

2.3 第 n 项 Hn 的值为

image.png 其满足递推关系:

image.png

题目解法

因此,这道题可以用递推公式来实现:

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]