题目
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
错误的思路
思路:由于只有一种括号,合法性就是在任何位置来看,左边的’(‘一定不小于’)的个数
因此,我根据n=3经过分析就得到了如下一个错误的结论:除第一个’(‘之外的所有位置均可以与除最后一个位置的’)’进行交换,即每交换一次就产生一次结果将其保存。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void swap(char *a,char *b){
char temp=*a;
*a=*b;
*b=temp;
}
char** generateParenthesis(int n, int* returnSize) {
if(n<1){
*returnSize=0;
return NULL;
}
//先将((()))这个最初的形式保存起来
char *temp=(char *)malloc((2*n+1)*sizeof(char));
if(temp==NULL)
exit(EXIT_FAILURE);
for(int i=0;i<2*n;i++){
if(i<n){
temp[i]='(';
}
else{
temp[i]=')';
}
}
temp[2*n]='\0';
//先将temp拷贝要result的第一个位置
int total=(n-1)*(n-1)+1;//由括号构成的合法的总数
char **result=(char **)malloc(total*sizeof(char *));
int index=0;
result[index]=(char *)malloc((2*n+1)*sizeof(char));
if(result[index]==NULL)
exit(EXIT_FAILURE);
strcpy(result[index],temp);
index++;
for(int i=1;i<n;i++){
//第一步:将copyTemp中除第一个'('之外的所有位置均可以与除最后一个位置的')'进行交换
for(int j=n;j<2*n-1;j++){
swap(&temp[i],&temp[j]);
result[index]=(char *)malloc((2*n+1)*sizeof(char));
if(result[index]==NULL)
exit(EXIT_FAILURE);
strcpy(result[index],temp);
index++;
swap(&temp[j],&temp[i]);//再将temp还原
}
}
*returnSize=index;
return result;
}
int main(void){
int k;
while(scanf("%d",&k)!=EOF&&k>0){
int returnSize=0;
char **result=generateParenthesis(k, &returnSize);
for(int i=0;i<returnSize;i++){
puts(result[i]);
}
}
}
这样的代码在n=4就不能够将所有的情况找出来。报错结果如下:
网上的思路
来自于博文:http://blog.csdn.net/yutianzuijin/article/details/13161721
针对一个长度为2n的合法排列,第1到2n个位置都满足如下规则:左括号的个数大于等于右括号的个数。所以,我们就可以按照这个规则去打印括号:假设在位置k我们还剩余left个左括号和right个右括号,如果left>0,则我们可以直接打印左括号,而不违背规则。能否打印右括号,我们还必须验证left和right的值是否满足规则,如果left>=right,则我们不能打印右括号,因为打印会违背合法排列的规则,否则可以打印右括号。如果left和right均为零,则说明我们已经完成一个合法排列,可以将其打印出来。通过深搜,我们可以很快地解决问题,
public class Solution {
List<String> result = new ArrayList<String>();
public List<String> generateParenthesis(int n) {
generate(n,n,"");
return result;
}
void generate(int leftNum,int rightNum,String s)
{
if(leftNum==0&&rightNum==0)
{
result.add(s);
}
if(leftNum>0)
{
generate(leftNum-1,rightNum,s+'(');
}
if(rightNum>0&&leftNum<rightNum)
{
generate(leftNum,rightNum-1,s+')');
}
}
}