题目描述:
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1 输出:["()"]
提示:
1 <= n <= 8
通过次数
747.1K
提交次数
964.3K
通过率
77.5%
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1 输出:["()"]
提示:
1 <= n <= 8
通过次数
747.1K
提交次数
964.3K
通过率
77.5%
题目分析:
这题并不难,我们可以类比前面第19题“有效的括号”的思路来做。力扣第19题:有效的括号
在前面那题“有效的括号中”,我们依次遍历给定的一个只包括'(' ')' '{' '}' '[' ']'的字符串s。如果遍历到左括号,就压入堆栈。如果遍历到右括号,就判断栈顶元素能不能和当前右括号匹配,如果说栈顶元素为空或者是当前元素不能与栈顶元素匹配,那就可以说明字符串s不是一个有效的括号集合;如果说当前元素能与栈顶元素匹配,那就删除栈顶元素并继续遍历下一个元素。当遍历结束时,栈为空就说明s有效,非空说明s无效。
既然可以用上述的方法来判断一个括号集是否有效,那么说明每个有效的括号集我们都能用上述的方法来生成。
我们再来分析一下此题。可以这样理解,给定一个数n,我们有n个 '(' 和n个 ')' 可以用,将n个 '(' 和n个 ')'放进一个字符串s中,输出每一种能让摆放好的字符串有效的组合。字符串s当中有2n个位置可以给你摆放,那我们就一个位置一个位置的摆放。对于每一个位置的摆放都有 '(' 和 ')' 两种选择。那我们就要考虑摆放这两种字符的条件。结合第19题“有效的括号”可知
一、能摆放'('的条件是:
1、(字符串s中当前位置)前面用掉的'('数量少于n个
二、能摆放')'的条件是:
1、(字符串s中当前位置)前面的'('数量比')'数量多
2、(字符串s中当前位置)前面用掉的')'数量少于n个
当摆完这个位置就摆下一个位置(递归调用下一层),直到摆完2n个位置就结束。
这是n==3时的流程图
目录
代码:
char *stack;
int top;
char **combinations;
int combinations_sizes;
int base;
//堆栈中左括号和右括号的个数
int left;
int right;
void backtrack(int index,int n)
{
if(index==2*n)
{//
char *temp=(char*)malloc(sizeof(char)*(2*n+1));
for(int i=0;i<2*n;i++) temp[i]=stack[i];
temp[2*n]='\0';
combinations[combinations_sizes]=temp;
combinations_sizes++;
return ;
}
if(left<n)
{
stack[top++]='(';
left++;
backtrack(index+1,n);
left--;
top--;
}
if(right<n&&left>right)
{
stack[top++]=')';
right++;
backtrack(index+1,n);
right--;
top--;
}
}
char ** generateParenthesis(int n, int* returnSize){
base=1500;
combinations=(char **)malloc(sizeof(char *)*base);
for(int i=0;i<base;i++) combinations[i]=NULL;
stack=(char *)malloc(sizeof(char)*(2*n+1));
top=0;
// combinations=0;
combinations_sizes=0;
left=right=0;
backtrack(0,n);
(*returnSize)=combinations_sizes;
return combinations;
}
补充:
除了上述的方法外,还可以用“暴力法”或者是“按照括号长度递归”的方法,有兴趣的可以自己去搜索。