leetcode:22. 括号生成
题目
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3输出:["((()))","(()())","(())()","()(())","()()()"]
输入:n = 1输出:["()"]
解答 & 代码
递归回溯
合法括号串 s 的性质:
- 左括号的数量一定等于右括号的数量
对于字符串的任意位置
i,s[0,...,i]包含的左括号数量 >= 右括号数量class Solution {private:vector<string> resultList; // 存储所有可能的结果string curResult; // 存储当前生成的括号字符串// 递归回溯,// 定义:传入未使用的左括号数量 leftCnt 和未使用的右括号数量 rightCnt,生成合法的括号字符串void dfs(int leftCnt, int rightCnt){// 递归结束条件 1: 若剩余未使用左括号数量大于剩余未使用的右括号数量// 说明当前生成的 curResult 中左括号数量大于右括号数量,肯定不合法,直接返回if(leftCnt > rightCnt)return;// 递归结束条件 2: 如果左、右括号都已用完,则直接将当前结果存入结果数组,并返回if(leftCnt == 0 && rightCnt == 0){resultList.push_back(curResult);return;}// 如果当前还有未使用的左括号,则在 curResult 尾部加上左括号if(leftCnt > 0){curResult += '('; // 选择dfs(leftCnt - 1, rightCnt); // 递归curResult.pop_back(); // 撤销选择}// 如果当前未使用的右括号数量大于未使用的左括号数量,则在 curResult 尾部加上右括号if(rightCnt > leftCnt){curResult += ')'; // 选择dfs(leftCnt, rightCnt - 1); // 递归curResult.pop_back(); // 撤销选择}}public:vector<string> generateParenthesis(int n) {dfs(n, n);return resultList;}};
复杂度分析:设括号对数为 N
时间复杂度 O(?):如果不剪枝,最终生成的字符串长为 2N,每个位置都有两种选择(
'('or')'),因此时间复杂度。但本题做了剪枝
- 空间复杂度 O(N):递归深度 2N
执行结果:
执行结果:通过执行用时:0 ms, 在所有 C++ 提交中击败了 100.00% 的用户内存消耗:11.4 MB, 在所有 C++ 提交中击败了 56.35% 的用户
