No.022:Generate Parentheses
问题:
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:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
官方难度:
Medium
翻译:
合并n个括号,生成所有n个括号组成的合理序列。
例子:
给定n=3,解集为
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
方法一:
- 初始的思想,考虑使用递归,每次优先获取n-1个括号所有情况下的集合,然后插入新的括号。
- 递归的终点是n=1,返回包含一个元素“()”的集合。
- 每次先加“(”,在第一个位置和一个“)”的下一个位置,插入左括号。
- 然后加右括号,从加入的左括号开始,统计左括号和右括号的个数,在左括号个数大于右括号个数的情况下,才可以加入右括号。
- 不难发现,虽然已经极力避免了,但是这种方法会出现很多的重复情况,所以需要一个Set集合去重,在递归结束之后,转化成List集合返回。
方法一的解题代码:
// 根据n-1的情况增加括号
public static List<String> method(int n) {
List<String> list = new ArrayList<>(getPharentheses(n));
return list;
} private static Set<String> getPharentheses(int n) {
Set<String> set = new HashSet<>();
if (n == 1) {
set.add("()");
} else {
Set<String> last = getPharentheses(n - 1);
for (String s : last) {
String s1 = "(" + s;
int l1 = 0;
int r1 = 0;
for (int j = 1; j < s1.length(); j++) {
if (s1.charAt(j) == '(') {
l1++;
} else {
r1++;
}
// 这里有重复的可能性
if (l1 > r1) {
set.add(s1.substring(0, j + 1) + ")" + s1.substring(j + 1));
}
}
// 先加左括号
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == ')') {
String str = s.substring(0, i + 1) + "(" + s.substring(i + 1);
// 左右括号计数
int l = 0;
int r = 0;
for (int j = i + 1; j < str.length(); j++) {
if (str.charAt(j) == '(') {
l++;
} else {
r++;
}
// 这里有重复的可能性
if (l > r) {
set.add(str.substring(0, j + 1) + ")" + str.substring(j + 1));
}
}
}
}
}
}
return set;
}
method
方法二:
- 显而易见,如果通过某种算法,没有重复的情况产生,那么方法的执行效率一定会快很多。
- 假设n=3。先加上所有的左括号,“(((”,那么右括号的可能性只有一个,那就是“((()))”。
- 然后回退一步,少加一个左括号,加上一个右括号,之后再加上这个左括号,会形成以下形式“(()())”。
- 后加的左括号再回退一步“(())()”。依次类推,直到这个左括号不能再加为止,回退至第一步,在一开始回退2个左括号,得到以下2种形式“()(())”和“()()()”。
- 发现回退的左括号为n时,结束。
- 解题的代码形式很简单,但是逻辑比较难捋通顺。
- 注意入参检查。
方法二的解题代码:
public static List<String> generateParenthesis(int n) {
if (n < 1) {
throw new IllegalArgumentException("Input error");
}
List<String> list = new ArrayList<>();
generate(n, n, "", list);
return list;
}
// 先加所有左括号,遍历所有可能性,然后回退一个左括号,依次类推
private static void generate(int left, int right, String current, List<String> list) {
// 先加左括号
if (left > 0) {
generate(left - 1, right, current + "(", list);
}
if (right > 0 && right > left) {
generate(left, right - 1, current + ")", list);
}
if (left == 0 && right == 0) {
list.add(current);
}
}
generateParenthesis
相关链接:
https://leetcode.com/problems/generate-parentheses/
PS:如有不正确或提高效率的方法,欢迎留言,谢谢!
No.022:Generate Parentheses的更多相关文章
- LeetCode OJ:Generate Parentheses(括号生成)
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- LeetCode第[22]题(Java):Generate Parentheses
题目:制造括号序列 难度:Medium 题目内容: Given n pairs of parentheses, write a function to generate all combination ...
- LeetCode 022 Generate Parentheses
题目描述:Generate Parentheses Given n pairs of parentheses, write a function to generate all combination ...
- 72. Generate Parentheses && Valid Parentheses
Generate Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...
- Generate Parentheses
Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...
- [LintCode] Generate Parentheses 生成括号
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- [CareerCup] 9.6 Generate Parentheses 生成括号
9.6 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-p ...
- 【题解】【排列组合】【回溯】【Leetcode】Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- leetcode022. Generate Parentheses
leetcode 022. Generate Parentheses Concise recursive C++ solution class Solution { public: vector< ...
随机推荐
- 学习Cassandra的开源电子书(中英文版)
学习Cassandra的开源电子书(中英文版)发布啦:http://teddymaef.github.io/learncassandra/ 之前发布了英文版,现在包含中文版了. 学习Cassandra ...
- ajax的使用:例题、ajax的数据处理
需要注意的是,调用的封装的数据库,和jQuery的保存地址 一.注册 (1)写文本框来进行用户名的验证 <input type="text" id="uid&quo ...
- datatable去重
两种方法1 数据库直接去除重复select distinct * from 表名去除了重复行distinct 2 对 DataTable直接进行操作DataTable dt=db.GetDt(&quo ...
- Minor【 PHP框架】3.路由、控制器、视图
框架Github地址:github.com/Orlion/Minor (如果觉得还不错给个star哦(^-^)V) 框架作者: Orlion 知乎:https://www.zhihu.com/peop ...
- C#单例模式详解
C#要实现单例模式必须要有以下三点: 声明私有静态成员.私有化构造函数.静态函数返回实例. private static GameManager s_GameManager=null; private ...
- 分享一个LiteDB做的简单考试系统辅助工具
凌晨,被安排在公司值班,因为台风“灿鸿”即将登陆,风力太大,办公楼,车间等重要部分需要关注.所以无聊,那就分享一下,今天给朋友临时做的一个小的考试系统辅助工具吧.其实非常小,需求也很简单,但是可以根据 ...
- Thrift简单实践
0.什么是RPC RPC(Remote Procedure Call - 远程过程调用),是通过网络从远程计算机上请求服务,而不需要了解底层网路技术的细节.简单点说,就是像调用本地服务(方法)一样调用 ...
- Util应用程序框架公共操作类(六):验证扩展
前面介绍了仓储的基本操作,下面准备开始扩展查询,在扩展查询之前,首先要增加两个公共操作类,一个是经常要用到的验证方法,另一个是Lambda表达式的操作类. 很多时候,我们会判断一个对象是否为null, ...
- Android随笔之——模拟按键操作的几种方式
前几天转过一篇Android上模拟按键操作.触屏事件的博客,昨天又去找了百度.谷歌了一下,写了一点简单的测试代码,留待不时之需.有需要看之前转载的那篇博客的请看这里→_→转:Android随笔之——使 ...
- 如何用Pivot实现行列转换
在Oracle中,如果要实现行列转换,较为常见的是用DECODE和CASE语句.对于简单的行列转行,DECODE和CASE语句尚能应付.在逻辑比较复杂,分组聚合较多的场景中,DECODE和CASE语句 ...