回溯 - 括号生成

📘 回溯法:生成合法括号组合(n 对)


🧩 功能说明

这段代码的功能是:输入一个整数 n,输出所有可能的 n 对合法括号组合

合法括号组合的定义是:括号必须成对匹配、顺序合理,不能出现像 ())( 这样的无效形式。


🧠 核心算法:回溯法(Backtracking)

通过递归地尝试每一个可能的分支选择(放左括号或右括号),构造出所有合法的组合路径。


🔍 类定义和主函数结构

#include <iostream>
#include <vector>
#include <climits>
#include <cmath>
#include <unordered_set>
using namespace std;

class Solution
{
public:
    vector<string> res;

    void backtrack(int n, int left, int right, string &temp)
    {
        if (left == n && right == n)
        {
            res.push_back(temp);
            return;
        }
        if (left < n)
        {
            temp += '(';
            backtarck(n, left + 1, right, temp);
            temp.pop_back();
        }
        if (left > right)
        {
            temp += ')';
            backtarck(n, left, right + 1, temp);
            temp.pop_back();
        }
    }
};

int main(int argc, char const *argv[])
{
    Solution solution;
    int n;
    cin >> n;
    string temp;
    solution.backtrack(n, 0, 0, temp);
    for (string s : solution.res)
    {
        cout << s << '\n';
    }
    return 0;
}

🧱 回溯逻辑详解(3 个 if 条件)

✅ 1. if (left == n && right == n)

  • 含义:左右括号都已放满,构造完成。
  • 作用:将当前字符串 temp 加入结果。
  • 注意:必须放在最前面,作为递归终止条件。

✅ 2. if (left < n)

  • 含义:左括号还没放满,可以尝试放 '('
  • 递归前temp += '('
  • 递归后temp.pop_back() 回退操作

✅ 3. if (left > right)

  • 含义:当前已有多余的左括号,可以安全地放一个右括号。
  • 保证:括号不会不合法(比如 ()))。
  • 递归逻辑与左括号类似。

🔄 条件顺序是否可以交换?

  • if (left == n && right == n) 必须在最前,作为终止条件。
  • left < nleft > right并行探索路径,可以交换顺序,不影响最终结果,只影响输出的排列顺序。

🌌 类比:平行世界探索

每次选择左括号或右括号,都会进入一个“平行世界”继续探索路径:

  • 当前状态不符合结束条件 → 分裂出不同分支
  • 所有路径都会回到上一个状态点继续探索(通过 pop_back()

🌲 示例搜索树图:n = 2

我们来举一个 n = 2 的回溯搜索图,展示递归路径:

                         ""
                      /      \
                  "("          (无效)
                /     \
           "(("       "()"        
           /             \
      "(())"            "()("
                         \
                         "()()"

说明:

  • "()" 的下一步可以再放一个左括号(变成 "()(")或者右括号(非法,不满足 left > right
  • 终止条件是左右括号都放完,得到结果 "(())""()()"

✅ 示例输入输出

输入:

2

输出:

(())
()()

posted @ 2025-04-23 15:25  vv大人  阅读(48)  评论(0)    收藏  举报