1 題目描述
數字 n 代表生成括號的對數,請你設計一個函數,用於能夠生成所有可能的並且 有效的 括號組合。
2 解題思路
- 方法一:深度優先遍歷
我們以 n = 2 爲例,畫樹形結構圖。方法是 “做減法”。
畫圖以後,可以分析出的結論:
(1)當前左右括號都有大於 0 個可以使用的時候,才產生分支;
(2)產生左分支的時候,只看當前是否還有左括號可以使用;
(3)產生右分支的時候,還受到左分支的限制,右邊剩餘可以使用的括號數量一定得在嚴格大於左邊剩餘的數量的時候,纔可以產生分支;
(4)在左邊和右邊剩餘的括號數都等於 0 的時候結算。
作者:liweiwei1419
鏈接:https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
3 解決代碼
- 方法一:深度優先遍歷《Java 代碼》
public class Solution {
// 做減法
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
// 特判
if (n == 0) {
return res;
}
// 執行深度優先遍歷,搜索可能的結果
dfs("", n, n, res);
return res;
}
/**
* @param curStr 當前遞歸得到的結果
* @param left 左括號還有幾個可以使用
* @param right 右括號還有幾個可以使用
* @param res 結果集
*/
private void dfs(String curStr, int left, int right, List<String> res) {
// 因爲每一次嘗試,都使用新的字符串變量,所以無需回溯
// 在遞歸終止的時候,直接把它添加到結果集即可,注意與「力扣」第 46 題、第 39 題區分
if (left == 0 && right == 0) {
res.add(curStr);
return;
}
// 剪枝(如圖,左括號可以使用的個數嚴格大於右括號可以使用的個數,才剪枝,注意這個細節)
if (left > right) {
return;
}
if (left > 0) {
dfs(curStr + "(", left - 1, right, res);
}
if (right > 0) {
dfs(curStr + ")", left, right - 1, res);
}
}
}
- 方法一:深度優先遍歷《python3 代碼》
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
cur_str = ''
def dfs(cur_str, left, right):
"""
:param cur_str: 從根結點到葉子結點的路徑字符串
:param left: 左括號還可以使用的個數
:param right: 右括號還可以使用的個數
:return:
"""
if left == 0 and right == 0:
res.append(cur_str)
return
if right < left:
return
if left > 0:
dfs(cur_str + '(', left - 1, right)
if right > 0:
dfs(cur_str + ')', left, right - 1)
dfs(cur_str, n, n)
return res