一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
Given n pairs of parentheses, write a function to
generate all combinations of well-formed parentheses
.
Example 1:
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
Example 2:
Input: n = 1
Output: ["()"]
Constraints:
1 <= n <= 8
看了给定的Solution,方法1、2、3,真是难懂,全是递归.....
自己琢磨出的求解方法,非递归,容易理解很多!
我的方法(本文的方法1): 先设置n=1,保存好();从n=2开始,依赖上次生成的括号字符串,遍历每个括号字符串和其中的每个括号字符,生成本次的括号字符串,再把本次的结果用于计算下次的,如此循环。
字符串拼接:用StringBuilder比"String+A+B+C"的运行时间有所缩短,效率有所提高。
package com.string;
import java.util.*;
/**
* @Author you guess
* @Date 2022/4/10 21:41
* @Version 1.0
* @Desc 生成指定数量的有效圆括号 2->()()、(())
*/
public class Leetcode_22_Generate_Parentheses {
/**
* 方法1:优化后
* Runtime: 24 ms, faster than 5.08% of Java online submissions for Generate Parentheses.
* Memory Usage: 45.4 MB, less than 10.08% of Java online submissions for Generate Parentheses.
*
* @param n
* @return
*/
public List<String> generateParenthesis(int n) {
List<String> list1 = new ArrayList<>();//存储总的结果
list1.add("()");
if (n == 1) {
return list1;
}
//n=2 3 4 ...
for (int i = 2; i <= n; i++) {
Set<String> set = new HashSet<>();//存储当次的结果
for (int j = 0; j < list1.size(); j++) {
String s = list1.get(j);
// set.add("()" + s);//左,多余的
// set.add(s + "()");//右,多余的
set.add("(" + s + ")");//外
set.addAll(this.addParenthesis(s));
}
list1 = new ArrayList<>(set);
}
return list1;
}
/**
* 优化后
*/
public Set<String> addParenthesis(String s) {
Set<String> set = new HashSet<>();
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
StringBuilder sb = new StringBuilder();
char c = s.charAt(i);
if (c == '(') {
//()()(()) -> (()())(()),这个比较容易忘记!!
if (stack.isEmpty()) {
sb.append("(").append(s, 0, i).append(")").append(s.substring(i));
set.add(sb.toString());
//set.add("(" + s.substring(0, i) + ")" + s.substring(i));
}
stack.push(i);
} else {
int left = stack.pop();
int right = i;
//在里面加一层(),比如([待加入])() -> ([()])()
sb.append(s, 0, left + 1).append("(").append(s, left + 1, right).append(")").append(s.substring(right));
set.add(sb.toString());
//set.add(s.substring(0, left + 1) + "(" + s.substring(left + 1, right) + ")" + s.substring(right));
}
}
return set;
}
class Entry {
Character c;
Integer index;
public Entry(Character c, Integer index) {
this.c = c;
this.index = index;
}
}
/**
* 这个也正确,不过不必使用Entry类
* 未优化
*
* @param s
* @return
*/
public Set<String> addParenthesisUseEntry(String s) {
Set<String> set = new HashSet<>();
Stack<Entry> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(') {
//()()(()) -> (()())(()),这个比较容易忘记!!
if (stack.isEmpty()) {
set.add("(" + s.substring(0, i) + ")" + s.substring(i));
}
Entry leftEntry = new Entry(s.charAt(i), i);
stack.push(leftEntry);
} else {
Entry leftEntry = stack.pop();
int left = leftEntry.index;// int left = leftEntry.getIndex() ; 同义
int right = i;
set.add(s.substring(0, left + 1) + "(" + s.substring(left + 1, right) + ")" + s.substring(right));
}
}
return set;
}
public static void main(String[] args) {
Leetcode_22_Generate_Parentheses main = new Leetcode_22_Generate_Parentheses();
//System.out.println(main.generateParenthesis(3));
System.out.println(main.generateParenthesisSolution(3));
}
}