Code 生成括号
来源:互联网 发布:郴州办公软件培训班 编辑:程序博客网 时间:2024/06/07 05:06
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:"((()))", "(()())", "(())()", "()(())", "()()()"
在LeetCode中有关括号的题共有三道,除了这一道的另外两道是 Valid Parentheses 验证括号和 Longest Valid Parentheses 最长有效括号,这道题给定一个数字n,让生成共有n个括号的所有正确的形式,对于这种列出所有结果的题首先还是考虑用递归Recursion来解,由于字符串只有左括号和右括号两种字符,而且最终结果必定是左括号3个,右括号3个,所以我们定义两个变量left和right分别表示剩余左右括号的个数,如果在某次递归时,左括号的个数大于右括号的个数,说明此时生成的字符串中右括号的个数大于左括号的个数,即会出现’)(‘这样的非法串,所以这种情况直接返回,不继续处理。如果left和right都为0,则说明此时生成的字符串已有3个左括号和3个右括号,且字符串合法,则存入结果中后返回。如果以上两种情况都不满足,若此时left大于0,则调用递归函数,注意参数的更新,若right大于0,则调用递归函数,同样要更新参数。代码如下:
C++ 解法一:
class Solution {public: vector<string> generateParenthesis(int n) { vector<string> res; generateParenthesisDFS(n, n, "", res); return res; } void generateParenthesisDFS(int left, int right, string out, vector<string> &res) { if (left > right) return; if (left == 0 && right == 0) res.push_back(out); else { if (left > 0) generateParenthesisDFS(left - 1, right, out + '(', res); if (right > 0) generateParenthesisDFS(left, right - 1, out + ')', res); } }};
Java 解法一:
public class Solution { public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<String>(); helper(n, n, "", res); return res; } void helper(int left, int right, String out, List<String> res) { if (left < 0 || right < 0 || left > right) return; if (left == 0 && right == 0) { res.add(out); return; } helper(left - 1, right, out + "(", res); helper(left, right - 1, out + ")", res); }}
再来看那一种方法,这种方法是CareerCup书上给的方法,感觉也是很巧妙的一种方法,这种方法的思想是找左括号,每找到一个左括号,就在其后面加一个完整的括号,最后再在开头加一个(),就形成了所有的情况,需要注意的是,有时候会出现重复的情况,所以我们用set数据结构,好处是如果遇到重复项,不会加入到结果中,最后我们再把set转为vector即可,参见代码如下::
n=1: ()
n=2: (()) ()()
n=3: (()()) ((())) ()(()) (())() ()()()
C++ 解法二:
class Solution {public: vector<string> generateParenthesis(int n) { set<string> t; if (n == 0) t.insert(""); else { vector<string> pre = generateParenthesis(n - 1); for (auto a : pre) { for (int i = 0; i < a.size(); ++i) { if (a[i] == '(') { a.insert(a.begin() + i + 1, '('); a.insert(a.begin() + i + 2, ')'); t.insert(a); a.erase(a.begin() + i + 1, a.begin() + i + 3); } } t.insert("()" + a); } } return vector<string>(t.begin(), t.end()); }};
Java 解法二:
public class Solution { public List<String> generateParenthesis(int n) { Set<String> res = new HashSet<String>(); if (n == 0) { res.add(""); } else { List<String> pre = generateParenthesis(n - 1); for (String str : pre) { for (int i = 0; i < str.length(); ++i) { if (str.charAt(i) == '(') { str = str.substring(0, i + 1) + "()" + str.substring(i + 1, str.length()); res.add(str); str = str.substring(0, i + 1) + str.substring(i + 3, str.length()); } } res.add("()" + str); } } return new ArrayList(res); }}
类似题目:
Remove Invalid Parentheses
Different Ways to Add Parentheses
Longest Valid Parentheses
Valid Parentheses
其它1:检测,如果左括号的个数到了n,则for循环补齐所有右括号,时间复杂度是不是会减低很多?因为剪枝减了将近一半。
public class Solution{ public List<string> GenerateParenthesis(int n) { var result = new List<string>(); if (n < 1) return result; var oneResult = new StringBuilder(); oneResult.Append("("); GenerateParenthesisDFS(1, 0, n, result, oneResult); return result; } private void GenerateParenthesisDFS( int leftParenthesisCount, int rightParenthesisCount, int n, List<string> result, StringBuilder oneResult) { if (leftParenthesisCount == n) { string tempResult = oneResult.ToString(); for (int i = 0; i < n - rightParenthesisCount; i++) { tempResult += ")"; } result.Add(tempResult); return; } else if (rightParenthesisCount > leftParenthesisCount) { return; } else { oneResult.Append("("); GenerateParenthesisDFS(leftParenthesisCount + 1, rightParenthesisCount, n, result, oneResult); oneResult.Remove(oneResult.Length - 1, 1); oneResult.Append(")"); GenerateParenthesisDFS(leftParenthesisCount, rightParenthesisCount + 1, n, result, oneResult); oneResult.Remove(oneResult.Length - 1, 1); } }}
其它2:提前剪枝
class Solution {public: vector<string> generateParenthesis(int n) { // Write your code here vector<string> res; string out; dfs(n, 0, 0, out, res); return res; } void dfs(int n, int left, int right, string &out, vector<string> &res) { if (left < n) { //Keep 塞左括号 out.push_back('('); dfs(n, left + 1, right, out, res); out.pop_back(); } if (right < left) { //避免出现右括号多余左括号的情况 out.push_back(')'); dfs(n, left, right + 1, out, res); out.pop_back(); } if (out.size() == n * 2) res.push_back(out); }};
转自:http://www.cnblogs.com/grandyang/p/4444160.html
- Code 生成括号
- 生成括号
- 生成括号
- 生成括号
- 简单括号匹配code
- LintCode : 生成括号
- LintCode-生成括号
- LintCode:生成括号
- LintCode:生成括号
- lintcode,生成括号
- 生成括号-lintcode
- lintcode -- 生成括号
- LintCode 生成括号
- DFS-lintcode生成括号
- 生成括号-LintCode
- lintcode刷题--生成括号
- leetcode-22-生成括号
- lintcode--生成括号
- 自媒体平台为什么强调垂直度
- NewsFragment
- 页面单选框<input type="radio">的分组与优化
- DataVP
- JSP基本语法
- Code 生成括号
- spoj371(费用流)
- Android填坑之旅(第十九篇)解决AdnroidStudio中build.gradle打开之后一直是loading......
- OutOfMemoryError系列(4): Metaspace
- 强化学习入门 : 一文入门强化学习 (Sarsa、Q learning、Monte-carlo learning、Deep-Q-Network等)
- 关于easyui中numberbox赋值问题
- FragmentHome
- 【D3D11游戏编程】学习笔记二:XNAMath之XMVECTOR
- Java 字符串操作