给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[ “((()))”, “(()())”, “(())()”, “()(())”, “()()()” ]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/generate-parentheses
将n对括号组合成正确的形式,即每个左括号都有一个右括号与之匹配。如n=3时,")(()()"第一个右括号没有对应左括号,所以错误。
二进制暴力法,即将其看成是一个二进制,‘(’看作1,‘)’看作0,
这样就可以确定区间。
同样当n=3时
5种情况用二进制表示为:
[111000,110100,110010,101100,101010]
可以发现他的取值范围为[101010,111000].十进制为[42,56].
同理当n=4时,取值范围为[10101010,11110000],十进制为[170,240]
所以用公式求出其最小值和最大值 a和b
for(int i=0; i
遍历两者之间的所有数字,寻找里面所有符合条件的数,转变为二进制1为"(", 0为")"
char ** generateParenthesis(int n, int* returnSize){
*returnSize=0;
int a=0,b=0;
for(int i=0;i<n;i++)
{
b=b+pow(2,n+i);
a=a+pow(2,i*2+1);
}
char *str1;
char **str2;
str1=(char *)malloc(sizeof(char)*10000);
str2=(char **)malloc(sizeof(char *)*10000);
for(int i=0;i<10000;i++)
str2[i]=(char *)malloc(sizeof(char)*10000);
//printf("%d %d\n",a,b);
for(int i=b;i>=a;i--)
{
int len=n*2;int flag=0;
str1[len]='\0';
int k=i;
while(k)
{
if(k%2==1)
{
str1[--len]='(';
flag+=1;
if(flag>0)break;
}
else
{
str1[--len]=')';
flag-=1;
}
k=k/2;
}
if(flag==0)
{
strcpy(str2[(*returnSize)++],str1);
}
}
return str2;
}
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string>res;
long long low = 0, high = 0;
//求区间范围(101010,111000)
for(int i = 1; i <= n; i++){
high += 1 << (2*n-i);
low += 1 << (i*2-1);
}
//遍历所有值
for(long long i = high; i >= low; i--){
long long num = i;
string s;
int flag = 0;
while(num){
if(num%2==1){
s = "(" + s;
flag++;
if(flag>0)break;
}else{
s = ")" + s;
flag--;
}
num /= 2;
}
if(flag==0)
res.push_back(s);
}
return res;
}
};
按照规定,添加括号,左括号数要小于n个,右括号数要小于左括号数
class Solution {
public:
vector<string>res;
void dfs(string s, int left, int right, int n){//左边 ,右边
if(left == n && right == n){
res.push_back(s);
return;
}
if(left < n)
dfs(s+"(",left+1,right,n);
if(left >right)
dfs(s+")",left,right+1,n);
}
vector<string> generateParenthesis(int n) {
dfs("",0,0,n);
return res;
}
};
由归纳法得出规律:
当我们清楚所有 i
那么,剩下 n-1 组括号有可能在哪呢?
【这里是重点,请着重理解】
剩下的括号要么在这一组新增的括号内部,要么在这一组新增括号的外部(右侧)。
既然知道了 i “(” + 【i=p时所有括号的排列组合】 + “)” + 【i=q时所有括号的排列组合】 其中 p + q = n-1,且 p q 均为非负整数。 事实上,当上述 p 从 0 取到 n-1,q 从 n-1 取到 0 后,所有情况就遍历完了。 注:上述遍历是没有重复情况出现的,即当 (p1,q1)≠(p2,q2) 时,按上述方式取的括号组合一定不同。class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<vector<string>>dp(n+1);
dp[0] = {""};
dp[1] = {"()"};
string s;
for(int i = 2; i <= n; i++){
for(int j = 0; j < i; j++){
for(string a : dp[j]){
for(string b : dp[i-j-1]){
s = "(" + b + ")" + a;
}
}
dp[i].push_back(s);
}
}
return dp[n];
}
};