Skip to content

Commit 8d674b9

Browse files
committed
二刷22
1 parent d5281d5 commit 8d674b9

File tree

4 files changed

+98
-17
lines changed

4 files changed

+98
-17
lines changed

docs/0022-generate-parentheses.adoc

+42-17
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,70 @@
11
[#0022-generate-parentheses]
2-
= 22. Generate Parentheses
2+
= 22. 括号生成
33

4-
{leetcode}/problems/generate-parentheses/[LeetCode - Generate Parentheses^]
4+
https://leetcode.cn/problems/generate-parentheses/[LeetCode - 22. 括号生成 ^]
55

6-
Given _n_ pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
6+
数字 `n` 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 *有效的* 括号组合。
77

8-
For example, given _n_ = 3, a solution set is:
8+
*示例 1:*
99

10-
[subs="verbatim,quotes,macros"]
11-
----
12-
[
13-
"((()))",
14-
"(()())",
15-
"(())()",
16-
"()(())",
17-
"()()()"
18-
]
19-
----
10+
....
11+
输入:n = 3
12+
输出:["((()))","(()())","(())()","()(())","()()()"]
13+
....
14+
15+
*示例 2:*
16+
17+
....
18+
输入:n = 1
19+
输出:["()"]
20+
....
21+
22+
23+
*提示:*
24+
25+
* `+1 <= n <= 8+`
2026
21-
== 解题分析
27+
28+
== 思路分析
2229

2330
image::images/0022-mindmap.png[{image_attr}]
2431

2532
使用回溯法解题时,需要关注的一个点是,**在递归调用时,为了保证结果是有效的括号对,则添加的闭区间符号不能多于开区间符号。也就是,保证添加在添加一个闭区间符号之前,要先添加了对应的开区间符号。所以,就要注意闭区间的判断,是跟开区间大小判断,而不是括号数量。**并不是所有的排列组合都符合我们的需求。
2633

27-
34+
也可以去掉回溯过程,使用深度优先遍历。
2835

2936
image::images/0022-0.png[{image_attr}]
3037

3138
image::images/0022-1.png[{image_attr}]
3239

3340
[[src-0022]]
41+
[tabs]
42+
====
43+
一刷::
44+
+
45+
--
3446
[{java_src_attr}]
3547
----
3648
include::{sourcedir}/_0022_GenerateParentheses.java[tag=answer]
3749
----
50+
--
51+
52+
二刷::
53+
+
54+
--
55+
[{java_src_attr}]
56+
----
57+
include::{sourcedir}/_0022_GenerateParentheses_2.java[tag=answer]
58+
----
59+
--
60+
====
3861

3962
== 思考题
4063

4164
有机会思考尝试一下广度优先遍历。
4265

4366
== 参考资料
4467

45-
. https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/[回溯算法(深度优先遍历)+ 广度优先遍历 + 动态规划 - 括号生成 - 力扣(LeetCode)^]
68+
. https://leetcode.cn/problems/generate-parentheses/solutions/35947/hui-su-suan-fa-by-liweiwei1419/[22. 括号生成 - 回溯算法(深度优先遍历)+ 广度优先遍历(Java)^]
69+
. https://leetcode.cn/problems/generate-parentheses/solutions/192912/gua-hao-sheng-cheng-by-leetcode-solution/[22. 括号生成 - 官方题解^]
70+
. https://leetcode.cn/problems/generate-parentheses/solutions/2071015/hui-su-bu-hui-xie-tao-lu-zai-ci-pythonja-wcdw/[22. 括号生成 - 回溯不会写?套路在此!^]

logbook/202503.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,11 @@ endif::[]
703703
|{doc_base_url}/0014-longest-common-prefix.adoc[题解]
704704
|✅ 解法很多,可以很好地开阔思路!
705705

706+
|{counter:codes2503}
707+
|{leetcode_base_url}/generate-parentheses/[22. Generate Parentheses^]
708+
|{doc_base_url}/0022-generate-parentheses.adoc[题解]
709+
|✅ 回溯。也可以去掉回溯过程,使用深度优先遍历。
710+
706711
|===
707712

708713
截止目前,本轮练习一共完成 {codes2503} 道题。

src/main/java/com/diguage/algo/leetcode/_0022_GenerateParentheses.java

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ public class _0022_GenerateParentheses {
3434
* Memory Usage: 45.3 MB, less than 5.16% of Java online submissions for Generate Parentheses.
3535
*
3636
* Copy from: https://leetcode.com/problems/generate-parentheses/solution/[Generate Parentheses solution - LeetCode]
37+
*
38+
* @author D瓜哥 · https://www.diguage.com
39+
* @since 2019-07-27 08:11
3740
*/
3841
public List<String> generateParenthesis(int n) {
3942
List<String> ans = new LinkedList<>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class _0022_GenerateParentheses_2 {
7+
// tag::answer[]
8+
9+
/**
10+
* @author D瓜哥 · https://www.diguage.com
11+
* @since 2025-05-16 23:23:48
12+
*/
13+
public List<String> generateParenthesis(int n) {
14+
List<String> result = new ArrayList<>();
15+
StringBuilder path = new StringBuilder(n * 2);
16+
backtrack(n, n, result, path);
17+
return result;
18+
}
19+
20+
private void backtrack(int left, int right,
21+
List<String> result, StringBuilder path) {
22+
if (left == 0 && right == 0) {
23+
result.add(path.toString());
24+
return;
25+
}
26+
// left < 0 表示已经添加了超量的左括号
27+
// left > right 表示右括号数量大于左括号
28+
if (left < 0 || left > right) {
29+
return;
30+
}
31+
char[] chars = {'(', ')'};
32+
for (int i = 0; i < chars.length; i++) {
33+
char c = chars[i];
34+
path.append(c);
35+
if (i == 0) {
36+
backtrack(left - 1, right, result, path);
37+
} else {
38+
backtrack(left, right - 1, result, path);
39+
}
40+
path.deleteCharAt(path.length() - 1);
41+
}
42+
}
43+
// end::answer[]
44+
public static void main(String[] args) {
45+
new _0022_GenerateParentheses_2()
46+
.generateParenthesis(3);
47+
}
48+
}

0 commit comments

Comments
 (0)