Python面试宝典第25题:括号生成

题目

数字n代表生成括号的对数,请设计一个函数,用于能够生成所有可能的并且有效的括号组合。

备注:1 <= n <= 8。

示例 1:

python 复制代码
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

python 复制代码
输入:n = 1
输出:["()"]

递归法

使用递归法求解此问题的基本思想是:将生成有效括号序列的问题分解为更小的子问题。对于每一对括号,我们都可以看作是在已有的有效括号序列基础上,或者在其前后分别添加一个左括号和右括号。为了保证序列的有效性,我们需要确保任何时候左括号的数量都不少于右括号的数量。因此,可以采用递归的方式,逐步构建所有可能的序列。使用递归法求解本题的主要步骤如下。

1、定义递归函数。函数接受两个参数,left 表示还可以使用的左括号数量,right 表示还可以使用的右括号数量,以及当前已经构造的括号序列curr_str。

2、递归终止条件。当left和right都为0时,说明当前序列是一个有效的括号组合,将其加入结果列表。

3、递归生成左括号。如果还有左括号可用(left > 0),则在当前序列后添加一个左括号,然后递归调用自身,减小left的计数。

4、递归生成右括号。如果右括号的数量少于等于左括号(right <= left),则不能添加右括号,因为这会导致序列无效。否则,在当前序列后添加一个右括号,然后递归调用自身,减小right的计数。

5、回溯。在每次递归调用返回后,撤销之前的选择,即回到上一层继续尝试其他可能性。

根据上面的算法步骤,我们可以得出下面的示例代码。

python 复制代码
def generate_brackets_by_recursion(n):
    def backtrack(left, right, curr_str, result):
        if left == 0 and right == 0:
            result.append(curr_str)
            return
        
        if left > 0:
            backtrack(left - 1, right, curr_str + '(', result)
        if right > left:
            backtrack(left, right - 1, curr_str + ')', result)

    result = []
    backtrack(n, n, '', result)
    return result

print(generate_brackets_by_recursion(3))
print(generate_brackets_by_recursion(1))

总结

递归法求解本题的时间复杂度主要取决于生成的括号组合的数量。对于n对括号,有效的括号组合数量遵循卡特兰数,其公式为C_n = (1/(n+1)) * (2n choose n)。卡特兰数的增长速度非常快,大约是 4^n / (sqrt(pi*n)*n^(3/2))。因此,时间复杂度为 O(C_n),即:O(4^n / sqrt(n))。空间复杂度主要由递归栈的深度决定,最坏情况下,递归栈的深度为2n,故空间复杂度为O(n)。

递归法特别适合括号生成类问题,因为它能自然地表达出问题的结构,即通过逐步构建解的空间树来寻找所有可能的解。然而,当n接近上限(比如:n=8)时,生成的组合数量会非常庞大,这可能会对程序的执行时间和内存使用提出较高的要求。因此,在实际应用中需要考虑递归的深度和效率问题。

相关推荐
纪元A梦2 小时前
贪心算法应用:化工反应器调度问题详解
算法·贪心算法
深圳市快瞳科技有限公司3 小时前
小场景大市场:猫狗识别算法在宠物智能设备中的应用
算法·计算机视觉·宠物
liulilittle3 小时前
OPENPPP2 —— IP标准校验和算法深度剖析:从原理到SSE2优化实现
网络·c++·网络协议·tcp/ip·算法·ip·通信
一个天蝎座 白勺 程序猿4 小时前
Python爬虫(47)Python异步爬虫与K8S弹性伸缩:构建百万级并发数据采集引擎
爬虫·python·kubernetes
XiaoMu_0015 小时前
基于Django+Vue3+YOLO的智能气象检测系统
python·yolo·django
superlls6 小时前
(算法 哈希表)【LeetCode 349】两个数组的交集 思路笔记自留
java·数据结构·算法
honder试试6 小时前
焊接自动化测试平台图像处理分析-模型训练推理
开发语言·python
^Rocky6 小时前
JavaScript性能优化实战
开发语言·javascript·性能优化
田里的水稻6 小时前
C++_队列编码实例,从末端添加对象,同时把头部的对象剔除掉,中的队列长度为设置长度NUM_OBJ
java·c++·算法
心本无晴.6 小时前
Python进程,线程
python·进程