1. 程式人生 > 實用技巧 >LeetCode(22):括號生成

LeetCode(22):括號生成

題目描述

解題思路

我們可以將問題改寫成:

現在有2n個位置,每個位置可以放 ( 或者 ),組成的所有括號組合中,哪些是合法的?

解決這個問題只需要分2步:

  1. 暴力列舉所有可能的情況,共有2的2n次方
  2. 在做選擇之前,進行“剪枝”

1、暴力列舉

只需要直接套用回溯演算法的框架即可:

  • 當path的長度為2n時,滿足結束條件,將path加入res中
  • 基於選擇列表【"(", ")"】,做選擇
  • 遞迴呼叫
  • 撤銷選擇
const dfs = function(path) {
    if(path.length === 2*n){
    res.push(path.join(""))
    }

    path.push('(')
    dfs(path)
    path.pop()

    path.push(')')
    dfs(path)
    path.pop()
}

2、“剪枝”

基於當前的路徑,如何判斷當前的括號組合是否合法?

不難發現:如果當前的路徑中,左括號數量小於右括號的數量,那麼這一定是不合法的括號組合

如何判斷當前路徑已經結束?

很簡單,只要看路徑的長度是否為2n即可

程式碼實現(JavaScript)

在核心函式dfs中,我們可以用2個變數left和right,記錄已經使用的左右括號數量

在做選擇之前:

  • 對當前路徑的合法性進行判斷
  • 判斷當前路徑是否滿足結束條件
var generateParenthesis = function(n) {
    const res = new Array()

    const dfs = function(left,right,path) {
        if(left>n || right>n) {
            return
        }
        if(left < right) {
            return
        }
        if(path.length === 2*n){
            res.push(path.join(""))
            return
        }
        
        path.push('(')
        dfs(left+1, right, path)
        path.pop()

        path.push(')')
        dfs(left, right+1,path)
        path.pop()
    }

    dfs(0,0,[])
    return res
};