Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
题目链接 22. Generate Parentheses
看到这个题目,马上想到了剑指offer上做过的一道题,12个高矮不同的人。
坏消息是我已经忘掉那个题目是怎么做的了,只记得用位运算,各种骚操作转化成01组合做出来,
12个高矮不同的人 问题描述: 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 这个笔试题,很YD,因为把某个递归关系隐藏得很深.
问题分析: 我们先把这12个人从低到高排列,然后,选择6个人排在第一排,那么剩下的6个肯定是在第二排. 用0表示对应的人在第一排,用1表示对应的人在第二排,那么含有6个0,6个1的序列,就对应一种方案.
比如000000111111就对应着 第一排:0 1 2 3 4 5 第二排:6 7 8 9 10 11
010101010101就对应着 第一排:0 2 4 6 8 10 第二排:1 3 5 7 9 11
与Leetcode上的题目思路很类似,将010101组合转化成( ) 即可
如果把0看成入栈操作,1看成出栈操作,就是说给定6个元素,合法的入栈出栈序列有多少个.
这就是catalan数,这里只是用于栈,等价地描述还有,二叉树的枚举,多边形分成三角形的个数,圆括弧插入公式中的
最为关键的一步是:1 2 3 4 5 6 7 int bit_cnt(int n) { int result = 0; //n&(n-1)作用:将n的二进制表示中的最低位为1的改为0 for (; n; n &= n - 1, ++result); return result; }
可以计算出对应个数的1,及其对应的值。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> using namespace std; int bit_cnt(int n) { int result = 0; //n&(n-1)作用:将n的二进制表示中的最低位为1的改为0 for (; n; n &= n - 1, ++result); return result; } int main(void) { int F[3], B[3];//前排、后排 int i, j, k, state, ok, ans = 0; for (state = 0; state < (1 << 6); ++state) { if (bit_cnt(state) == 3)//有3个1 { i = j = 0; for (int k = 0; k < 6; ++k) { if (state&(1 << k))//第K位是不是1 F[i++] = k; else B[j++] = k; } ok = 1; for (k = 0; k < 3; ++k) { if (B[k] < F[k])//后排比前排小,跳出 { ok = 0; break; } } if (ok == 1) { cout << state << endl; cout << F[0] << " " << F[1] << " " << F[2] << " " << endl; cout << B[0] << " " << B[1] << " " << B[2] << " " << endl; cout << endl; } ans += ok; } } cout << ans << endl; return 0; }
回到本题 问题描述 Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { public: int bit_cnt(int n) { int result = 0; //n&(n-1)作用:将n的二进制表示中的最低位为1的改为0 for (; n; n &= n - 1, ++result); return result; } vector<string> generateParenthesis(int n) { int f, b, k, state, ans = 0; vector<string> answer; for (state = 0; state < (1 << n * 2); ++state) { if (bit_cnt(state) == n) { string res = ""; f = 0, b = 0;//front,back 前后括号都是0个 for (k = 0; k < n * 2; k++) { if (state&(1 << k)) {//如果第k位是1 res += '('; f++; } else { res += ')'; b++; } if (f < b) break; } if (res.size() == n * 2) answer.push_back(res); } } return answer; } };
大体上的思路都是一回事,这种递归嘛,应该也算不上。
也许就是骚操作吧