本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
22. 括号生成
来源:力扣(LeetCode)
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
提示:
-
1 <= n <= 8
解法
- 生成所有组合之后再判断是否合法:先使用递归生成所有的可能扩号组合,之后再去判断每种括号组合是否合法;
- 基于括号的关系,能够在生成括号的同时就能知道是否是合法组合:括号对的个数为n,则左括号的个数也是n个,左括号随时都能放进去,只要左括号的个数不超过n个,而右括号需要考虑一下左括号的个数,当右括号的个数小于左括号的时候,是可以放进去的,另外,右括号也不能超过n个。但由于左括号是不大于n的,所以右括号小于等于左括号个数的时候 已经满足这个限制了。
- 用括号与n-1的结果进行任何组合 : 其中n递归到1; 然后将'()'放到n-1结果中任何一个位置即可,进行字符串拼接;
代码实现
先递归生成所有组合,再去判断合法性
python实现
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
ans = []
# 先生成所有可能的组合,并对每种组合进行判断是否符合标准
def helper(ss=[]):
if len(ss) == 2*n:
if self.valid(''.join(ss)):
ans.append(''.join(ss))
else:
ss.append('(')
helper(ss)
ss.pop()
ss.append(')')
helper(ss)
ss.pop()
helper()
return ans
def valid(self, s):
counts = 0
for char in s:
if char == '(':
counts += 1
else:
counts -= 1
if counts < 0:
return False
return counts == 0
c++实现
class Solution {
private:
vector<string> ans;
public:
bool valid(string s) {
int counts = 0;
for(char ch: s) {
if (ch == '(')
counts++;
else
counts--;
if (counts < 0)
return false;
}
return counts == 0;
}
string convert(vector<char> cs, int size) {
string s;
for(int i=0; i<size; i++)
s += cs[i];
return s;
}
void _generateParenthesis(vector<char> cs, int n) {
if (cs.size() == 2 * n) {
string s = convert(cs, 2*n);
if (valid(s))
ans.push_back(s);
}
else {
cs.push_back('(');
_generateParenthesis(cs, n);
cs.pop_back();
cs.push_back(')');
_generateParenthesis(cs, n);
cs.pop_back();
}
}
vector<string> generateParenthesis(int n) {
_generateParenthesis({}, n);
return ans;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度:
递归生成的同时基于左右括号数量关系进行组合删减
python实现
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
ans = []
def helper(l, r, s):
# 递归结束条件
if len(s) == 2*n:
ans.append(s)
if len(s) > 2 * n:
return
# 开始处理
if l < n:
helper(l+1, r, s+'(')
if r < l and r < n:
helper(l, r+1, s+')')
helper(0, 0, '')
return ans
c++实现
class Solution {
private:
vector<string> ans;
public:
int _generateParenthesis(int left, int right, int n, string s) {
if (s.size() == 2 * n)
ans.push_back(s);
if (s.size() > 2*n)
return -1;
if (left < n)
_generateParenthesis(left+1, right, n, s+'(');
if (right < left)
_generateParenthesis(left, right+1, n, s+')');
return 0;
}
vector<string> generateParenthesis(int n) {
_generateParenthesis(0, 0, n, "");
return ans;
}
};
复杂度分析
"()"与n-1结果的任意字符串拼接
python实现
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
if n == 1:
return ['()']
res = set()
for i in self.generateParenthesis(n-1):
for j in range(len(i)+2):
res.add(i[0:j] + '()' + i[j:])
return list(res)
c++实现
class Solution {
public:
vector<string> generateParenthesis(int n) {
if (n==1)
return {"()"};
unordered_map<string, int> mp;
vector<string> res;
string tmp;
for (auto& s: generateParenthesis(n-1)) {
for (int i=0; i < 2*(n-1); i++) {
tmp = s.substr(0, i) + "()" + s.substr(i, 2*(n-1));
if (mp[tmp] == 0) {
++mp[tmp];
res.push_back(tmp);
}
}
}
return res;
}
};
复杂度分析