LeetCode—— 括号生成
题目地址:https://leetcode-cn.com/problems/generate-parentheses/
解题思路:我的解题思路是通过二进制来进行遍历,(比如说"((()))"可以看成111000,三组括号的所有排列形式就是00000~111111,然后从中只取3个1的组合)虽然过了但是运行时间较长,题解给了一种回溯算法比较好。
class Solution { bool isValid(string s) { stack<char> q; for (int i = 0; i < s.size(); i++) { if (q.empty()) q.push(s[i]); else { if (q.top() == '('&&s[i] == ')') q.pop(); else q.push(s[i]); } } if (q.empty()) return true; else return false; } string trueString(int m,int n) { int flag = 0; int t = 2*n; char *ans=new char[t+1]; while (m) { if (m & 1) { flag++; ans[--t] = '('; } else ans[--t] = ')'; m = m >> 1; } ans[2*n] = '\0'; if (flag == n) return (string)ans; else return "-1"; } public: vector<string> generateParenthesis(int n) { int m = pow(2, 2 * n) - 1;//使用二进制来进行遍历 vector<string> ans; string t; for (int i = 0; i < m; i++) { if (!(i & 1)) {//奇数肯定不满足; t = trueString(i, n); if (t != "-1"&&isValid(t)) ans.push_back(t); } } return ans; } };
从上到下依次是 题解的暴力算法,按序列的长度递归,回溯法,以及我自己的
之后看了别人的题解发现可以用DFS,想了想后还真的可以就自己再写了一下过了。
class Solution { private: vector<string> ans; void dfs(int left, int right, string cur) {//left左括号的个数,right右括号的个数 if (left == 0 && right == 0) { ans.push_back(cur); return; } if (left > 0) dfs(left - 1, right, cur + "("); if (right > left) dfs(left, right-1, cur + ")"); } public: vector<string> generateParenthesis(int n) { string cur = ""; dfs(n, n, cur); return ans; } };