生成括号问题中回溯算法的栈回溯逻辑及pop时机解析
回溯算法中
pop逻辑与生成括号问题的执行解析 核心逻辑:回溯是「试错+撤销选择」
回溯的本质是走不通就回头,回头时必须把刚才选的路擦掉。每一次向当前路径currCombo中添加字符(append),都是选择了一条分支;当这条分支的所有可能性都探索完毕后,必须用pop把这个字符移除,才能回到上一个岔路口,尝试其他分支。
生成括号问题的代码与pop对应关系
先看标准可行代码:
def generateParenthesis(n): result = [] def backtrack(currCombo, openN, closeN): # 基准情况:括号长度达标,记录结果 if len(currCombo) == 2 * n: result.append(''.join(currCombo)) return # 尝试加左括号 if openN < n: currCombo.append('(') backtrack(currCombo, openN + 1, closeN) currCombo.pop() # 撤销左括号选择 # 尝试加右括号 if closeN < openN: currCombo.append(')') backtrack(currCombo, openN, closeN + 1) currCombo.pop() # 撤销右括号选择 backtrack([], 0, 0) return result
这里的pop和append是严格一一对应的:每加一个字符,递归探索完所有子分支后,必须撤销这个选择,否则路径会带着之前的分支残留,导致后续分支的选择错误。
生成((()))后的回溯过程拆解(n=3)
当生成第一个结果((()))时,递归调用链已经走到最深层:
路径:
['(', '(', '(', ')', ')', ')'],触发基准条件,加入结果后返回上一层。
接下来的回溯(pop)过程分4步,对应你提到的“3个右括号+1个左括号”:
- 第一次pop:从最深层返回后,执行
currCombo.pop(),去掉最后一个),路径变为['(', '(', '(', ')', ')'],当前递归层结束,返回上一层。 - 第二次pop:回到上一层(对应加倒数第二个
)的递归),执行pop()去掉倒数第二个),路径变为['(', '(', '(', ')'],递归层结束,返回上一层。 - 第三次pop:回到加倒数第三个
)的递归层,执行pop()去掉这个),路径变为['(', '(', '('],递归层结束,返回上一层。 - 第四次pop:回到加第三个
(的递归层,执行pop()去掉这个(,路径变为['(', '('],递归层结束,回到上一个岔路口。
为什么要这些pop?
回到路径['(', '(']时,左括号分支(即加第三个(的分支)已经探索完毕,现在可以尝试右括号分支:
- 此时
closeN=0 < openN=2,满足加右括号的条件,执行append(')'),路径变为['(', '(', ')'],进入新的递归链,最终生成第二个结果(()())。
如果没有这些pop,路径会一直停留在['(', '(', '(', ')', ')', ')'],无法回到岔路口选择其他分支,自然生成不了后续的有效括号组合。
关键总结
- pop的时机:紧跟在递归调用之后——递归调用代表当前选择的所有子分支已探索完毕,必须撤销选择回到岔路口。
- pop的次数:每一次
append对应且仅对应一次pop,保证路径始终是当前分支的纯净选择序列。 - 可视化技巧:可以在递归函数中添加打印语句,实时输出进入递归和pop后的路径,直观看到每一步的变化,比如:
def backtrack(currCombo, openN, closeN): print(f"进入: {currCombo} | 左括号数: {openN} | 右括号数: {closeN}") if len(currCombo) == 2 * n: result.append(''.join(currCombo)) print(f"找到结果: {''.join(currCombo)}") return if openN < n: currCombo.append('(') backtrack(currCombo, openN + 1, closeN) currCombo.pop() print(f"撤销左括号后: {currCombo}") if closeN < openN: currCombo.append(')') backtrack(currCombo, openN, closeN + 1) currCombo.pop() print(f"撤销右括号后: {currCombo}")
内容的提问来源于stack exchange,提问作者calvin2011
相关产品推荐
相关产品推荐

