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时,还可放置新的左括号;当右括号出现次数小于左括号出现次数时,就可以放置新的右括号。
回溯方法的步骤如下:
1) 定义一个解空间,它包含问题的解。
2) 用适于搜索的方式组织该空间。
3) 用深度优先法搜索该空间,利用限界函数避免移动到不可能产生解的子空间。
回溯算法的一个有趣的特性是在搜索执行的同时产生解空间。在搜索期间的任何时刻,仅保留从开始节点到当前节点的路径。
因此,回溯算法的空间需求为O(从开始节点起最长路径的长度)。这个特性非常重要,因为解空间的大小通常是最长路径长度的指数或阶乘。
所以如果要存储全部解空间的话,再多的空间也不够用。
【对于递归的思想、中间过程数据的存储还是不够熟悉,没事的,加油!】
另外,n对括号可形成的有效括号组合为卡特兰数,h(n) = C(2n,n)/(n+1)
1 #include "stdafx.h" 2 #include <iostream> 3 #include <vector> 4 #include <string> 5 using namespace std; 6 7 void generator(vector<string> &result, string s, int left, int right); 8 9 vector<string> generateParentheses(int n) 10 { 11 vector<string> result; 12 string s; 13 generator(result, s, n, n); 14 return result; 15 } 16 17 void generator(vector<string> &result, string s, int left, int right) 18 { 19 if(left == 0 && right == 0)//s已包括所有左右括号 20 result.push_back(s); 21 if(left > 0) 22 generator(result, s+'(', left-1, right); 23 if(right > 0 && right > left) 24 generator(result, s+')', left, right-1); 25 } 26 27 int main() 28 { 29 int n = 6; 30 vector<string> result = generateParentheses(n); 31 int i=1; 32 for(auto c : result) 33 { 34 cout << i << " : " << c << endl; 35 i++; 36 } 37 38 return 0