22. 括号生成
题目描述:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
思路:找到所有括号的组合方式看起来比较复杂。所以可以尝试换个思路:如果“(”对应数字1,“)”对应数字-1呢?
通过观察可以发现这样一个规律:
凡是有效的括号组合,转化成数字,任意前n项和都不小于0!
比如:“()()()”
前1位:1>=0;前2位:1+(-1)=0>=0;前3位:1+(-1)+1=1>=0;
......以此类推,前n位数字和均大于等于0.
又比如:“((()))”
前3位:1+1+1=3>=0;前4位:1+1+1+(-1)=2>=0;前5位:1+1+1+(-1)+(-1)=1>=0;
......依然满足规律。
至此,就能想到这样一个思路:
1.目标为n时,可以转化为n个-1和n个1
2.求这串数字的所有排列
3.满足以上规律的就是有效的括号组合
4.最后一步再将数字组合转化成括号组合
整个过程需要一些小的工具:
1.求全排列的函数:next_permutation
2.数字转化成括号:容器map
代码:
class Solution { public: vector<string> generateParenthesis(int n) { vector<string>res; vector<vector<int>>mid; vector<int>temp; for(int i = 0;i < n;i++) temp.push_back(-1); for(int i = 0;i < n;i++) temp.push_back(1); while(next_permutation(temp.begin(),temp.end())){ int flag = 1; int target = 0; for(auto i:temp){ target += i; if(target<0){ flag = 0; break; } } if(flag==1) mid.push_back(temp); } map<int,string>invert; invert.insert(map<int,string>::value_type(-1,")")); //注意-1和1分别对应哪个括号 invert.insert(map<int,string>::value_type(1,"(")); for(auto i:mid){ string s; for(auto j:i) s += invert[j]; //注意用[],不是() res.push_back(s); } return res; } };