​BM60 括号生成​

知识点​递归​

描述

给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。

例如,给出n=3,解集为:"((()))", "(()())", "(())()", "()()()", "()(())"

数据范围:[典型]BM60 括号生成-中等_括号要求:空间复杂度 [典型]BM60 括号生成-中等_字符串_02,时间复杂度 [典型]BM60 括号生成-中等_字符串_03

示例1

输入:

1

复制返回值:

["()"]

复制

示例2

输入:

2

复制返回值:

["(())","()()"]


题解

可以将题目看成分别有N个左括号和右括号,每次可以取出一到多个左括号或者右括号,让他们组成合法的括号对。

要符合合法的括号对,则必须是左括号的个数等于右括号的个数。假设前面我们已经使用i个左右括号组合成了合法的括号对,然后接着必须取左括号(也就是不能取右括号,这个就是有括号的限制条件),但是当左括号较多的时候,我们即可以取左括号,又可以取有括号。

我们使用递归对这个问题求解,步骤如下:

  1. 每次从左括号中取一个放到字符串中,但是左括号总的个数必须小于等于n
  2. 当取了左括号后,可能需要取右括号,取有括号时有括号的个数必须小于左括号的个数,此时将有括号追加到字符串中
  3. 当左右括号个数都为N的时候,将字符串加入结果数组中

代码如下:

#include <bits/stdc++.h>

using namespace std;

void recursion(int left, int right, string temp, vector<string> &res, int n)
{
//左右括号都用完了,就加入结果
if (left == n && right == n)
{
res.push_back(temp);
return;
}
//使用一次左括号
if (left < n)
{
recursion(left + 1, right, temp + "(", res, n);
}
//使用右括号时,右括号个数必须少于左括号
if (right < n && left > right)
{
recursion(left, right + 1, temp + ")", res, n);
}
}

vector<string> generateParenthesis(int n)
{
vector<string> res;
string temp;
recursion(0, 0, temp, res, n);
return res;
}