22. 括号生成
题目描述
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
题解:
法一:
暴力枚举所有括号序列,然后判断每个括号序列是否合法。
时间复杂度: O ( n ∗ 2 2 n ) O(n * 2^{2n}) O(n∗22n)
空间复杂度: O ( n ) O(n) O(n)
法一代码:
class Solution {
public:
vector<string> ret;
bool isLegal( string& s ) {
int n = s.length();
if ( !n ) return true;
if ( s[0] == ')' || s[n - 1] == '(' ) return false;
int balance = 0;
for( char& ch : s ) {
if ( ch == '(' ) ++balance;
else --balance;
if ( balance < 0 ) return false;
}
return balance == 0;
}
void dfs( string ans, int left, int right ) {
if ( !left && !right ) {
if ( isLegal(ans) ) ret.push_back( ans );
return;
}
if ( left ) dfs( ans + '(', left - 1, right );
if ( right ) dfs( ans + ')', left, right - 1 );
}
vector<string> generateParenthesis(int n) {
dfs( "", n, n );
return ret;
}
};
/*
时间:8ms,击败:42.36%
内存:18.2MB,击败:6.76%
*/
慢的离谱,内存消耗也大。
法二:
其实在生成括号序列时,我们是可以控制只生成合法括号序列:只要递归过程保证 left <= right
即可。
时间复杂度: O ( n n + 1 ( 2 ∗ n n ) ) = ( 2 ∗ n n ) O(\frac{n}{n+1}{2*n \choose n})={2*n \choose n} O(n+1n(n2∗n))=(n2∗n)
空间复杂度: O ( n ) O(n) O(n)
法二代码:
class Solution {
public:
vector<string> ret;
void dfs( string ans, int left, int right ) {
if ( !left && !right ) {
ret.push_back( ans );
return;
}
if ( left > right ) return;
if ( left ) dfs( ans + '(', left - 1, right );
if ( right ) dfs( ans + ')', left, right - 1 );
}
vector<string> generateParenthesis(int n) {
dfs( "", n, n );
return ret;
}
};
/*
时间:0ms,击败:100.00%
内存:13.6MB,击败:54.31%
*/