Day15 括號生成
阿新 • • 發佈:2021-02-17
技術標籤:LeetCode刷題集演算法leetcode資料結構
數字 n 代表生成括號的對數,請你設計一個函式,用於能夠生成所有可能的並且 有效的 括號組合
https://leetcode-cn.com/problems/generate-parentheses/
示例1:
輸入:n = 3
輸出:["((()))","(()())","(())()","()(())","()()()"]
示例2:
輸入:n = 1
輸出:["()"]
提示:
1 <= n <= 8
Java解法
思路:
看起來有點懵逼,但實際上是一個可細化的操作,可以看成,一對括號與上一次操作的各種排列組合,中間()()這種操作或出現重複所有會少一個,所以細化後的思路
我果然太年輕,前一輪無效不代表後一輪無效,對結果瞎了我的眼先算最小,將最小的結果帶入下一輪- 來句教訓,做不來的時候千萬不要死磕,搞得遞迴都不會寫了
- 參考官方解的暴力解,寫出能執行的答案,遞迴計算所有可能組合,新增時計算有效性
- 再加上回溯控制
package sj.shimmer.algorithm;
import java.util.ArrayList;
import java.util.List;
/**
* Created by SJ on 2021/2/8.
*/
class D15 {
public static void main(String[] args) {
System.out.println(generateParenthesis(4));
}
public static List<String> generateParenthesis(int n) {
List<String> strings = new ArrayList<>();
if (n == 0) {
strings.add("()" );
return strings;
}
char[] chars = new char[n * 2];
get(strings, chars, 0);
System.out.println(strings);
strings.clear();
backtrack(strings,chars,0,0);
System.out.println(strings);
return strings;
}
private static void get(List<String> strings, char[] chars, int index) {
if (index >= chars.length) {
int balance = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i]=='(') {
balance++;
}else {
balance--;
}
if (balance<0) {
break;
}
}
if (balance==0) {
strings.add(new String(chars));
}
return;
}
chars[index]='(';
get(strings,chars,index+1);
chars[index]=')';
get(strings,chars,index+1);
}
private static void backtrack(List<String> strings, char[] chars, int index,int leftNum) {
if (index >= chars.length) {
int balance = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i]=='(') {
balance++;
}else {
balance--;
}
if (balance<0) {
break;
}
}
if (balance==0) {
strings.add(new String(chars));
}
return;
}
chars[index]='(';
backtrack(strings,chars,index+1,leftNum+1);
if (leftNum>index/2) {
chars[index]=')';
backtrack(strings,chars,index+1,leftNum);
}
}
}
官方解
-
暴力解
參考上方
- 時間複雜度: O(2^2n*n)
- 空間複雜度:O(n)
-
回溯
思路如上,但加入有效控制,在進入下一次呼叫之前,記錄有效性相關引數(已有左括號數量),與官方解寫法稍不一致,但同樣可用