力扣Hot100-22 括号生成
全部刷题与学习记录
原题目
题目地址:22. 括号生成
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
考查知识点
递归应用
好的解法
参考公众号【数据结构与算法】的一种深度优先遍历解法。
首先观察括号组合有两种规律:
- 任意括号(满足题目条件)一定是 左括号数量 = 右括号数量
- 在任意括号中的任意位置(截断到当前位置),一定是 左括号数量 > 右括号数量
使用递归三步法来分析这个问题:
- 递归函数参数及返回值: 需要遍历所有情况时不需要返回值,需要找某条路径的时候才需要返回值。本题要遍历所有组合状况,因此不需要返回值。需要一个字符串数组
res
记录所有满足条件的字符串,需要left
与right
两个计数器表示剩下的左右括号数量,需要一个字符串curStr
表示当前组合 - 函数结束条件: 根据left与right一共有三种情况。①left == 0 && right == 0:所有左右括号全部匹配完毕,没有剩余,将curStr加入res;②left > right:说明curStr中右括号数量超过左括号,不合法;③left < 0 || right < 0:剩余括号已经分配完,不能继续分配
- 递归循环逻辑,就是不断分配左右括号,记得将对应的括号加入curStr
#include<iostream>
#include <vector>
using namespace std;
class Solution {
private:
vector<string> res;
void dfs(int left, int right, string curStr) {
if (left == 0 && right == 0) {
res.push_back(curStr);
return;
}
if (left < 0 || right < 0) {
//左括号或者右括号选完了
return;
}
else if (left > right) {
//剩余的左括号多
return;
}
//加左括号
dfs(left - 1, right, curStr + "(");
//加右括号
dfs(left, right - 1, curStr + ")");
}
public:
vector<string> generateParenthesis(int n) {
dfs(n, n, "");
return res;
}
};