Leet Code 022 Generate Parentheses

給出 n 代表生成括號的對數,請你寫出一個函數,使其能夠生成所有可能的並且有效的括號組合。

例如,給出 n = 3,生成結果爲:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

思路: 回溯法

非常牛逼的講解,需要這樣的人來給我們講算法

以Generate Parentheses爲例,backtrack的題到底該怎麼去思考?

所謂Backtracking都是這樣的思路:在當前局面下,你有若干種選擇。那麼嘗試每一種選擇。如果已經發現某種選擇肯定不行(因爲違反了某些限定條件),就返回;如果某種選擇試到最後發現是正確解,就將其加入解集

所以你思考遞歸題時,只要明確三點就行:選擇 (Options),限制 (Restraints),結束條件 (Termination)。即“ORT原則”(這個是我自己編的)

對於這道題,在任何時刻,你都有兩種選擇:

  1. 加左括號。
  2. 加右括號。

同時有以下限制:

  1. 如果左括號已經用完了,則不能再加左括號了。
  2. 如果已經出現的右括號和左括號一樣多,則不能再加右括號了。因爲那樣的話新加入的右括號一定無法匹配。

結束條件是:
左右括號都已經用完。

結束後的正確性:
左右括號用完以後,一定是正確解。因爲1. 左右括號一樣多,2. 每個右括號都一定有與之配對的左括號。因此一旦結束就可以加入解集(有時也可能出現結束以後不一定是正確解的情況,這時要多一步判斷)。

遞歸函數傳入參數:
限制和結束條件中有“用完”和“一樣多”字樣,因此你需要知道左右括號的數目。
當然你還需要知道當前局面sublist和解集res。

因此,把上面的思路拼起來就是代碼:

    if (左右括號都已用完) {
      加入解集,返回
    }
    //否則開始試各種選擇
    if (還有左括號可以用) {
      加一個左括號,繼續遞歸
    }
    if (右括號小於左括號) {
      加一個右括號,繼續遞歸
    }

你帖的那段代碼邏輯中加了一條限制:“3. 是否還有右括號剩餘。如有才加右括號”。這是合理的。不過對於這道題,如果滿足限制1、2時,3一定自動滿足,所以可以不判斷3。

這題其實是最好的backtracking初學練習之一,因爲ORT三者都非常簡單明顯。你不妨按上述思路再梳理一遍,還有問題的話再說。

以上文字來自 1point3arces的牛人解答

複雜度分析

我們的複雜度分析依賴於理解 generateParenthesis(n) 中有多少個元素。這個分析超出了本文的範疇,但事實證明這是第 n 個卡塔蘭 數.

時間複雜度:O(4^n/sqrt(n)),在回溯過程中,每個有效序列最多需要 n 步。

空間複雜度:O(4^n/sqrt(n)),並使用O(n) 的空間來存儲序列。

class Solution:
    def generateParenthesis(self, n):
        # if n == 0: return ''
        self.res = []
        self.gen('', n, n)
        return self.res
    import pysnooper
    @pysnooper.snoop()
    def gen(self, sub, left, right):
        if left == 0 and right == 0:
            self.res.append(sub)
            return

        if left > 0:
            self.gen(sub+'(', left-1, right)
        if right > left:
            self.gen(sub+')', left, right-1)
s.generateParenthesis(3)
Starting var:.. left = 3
Starting var:.. right = 3
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = ''
21:24:19.191288 call         9     def gen(self, sub, left, right):
21:24:19.193285 line        10         if left == 0 and right == 0:
21:24:19.193285 line        14         if left > 0:
21:24:19.194286 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 2
Starting var:.. right = 3
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '('
21:24:19.194286 call         9     def gen(self, sub, left, right):
21:24:19.194286 line        10         if left == 0 and right == 0:
21:24:19.196285 line        14         if left > 0:
21:24:19.196285 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 1
Starting var:.. right = 3
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(('
21:24:19.197284 call         9     def gen(self, sub, left, right):
21:24:19.197284 line        10         if left == 0 and right == 0:
21:24:19.197284 line        14         if left > 0:
21:24:19.197284 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 0
Starting var:.. right = 3
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '((('
21:24:19.202280 call         9     def gen(self, sub, left, right):
21:24:19.202280 line        10         if left == 0 and right == 0:
21:24:19.203282 line        14         if left > 0:
21:24:19.203282 line        16         if right > left:
21:24:19.203282 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 2
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '((()'
21:24:19.204280 call         9     def gen(self, sub, left, right):
21:24:19.204280 line        10         if left == 0 and right == 0:
21:24:19.204280 line        14         if left > 0:
21:24:19.204280 line        16         if right > left:
21:24:19.204280 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '((())'
21:24:19.204280 call         9     def gen(self, sub, left, right):
21:24:19.205280 line        10         if left == 0 and right == 0:
21:24:19.205280 line        14         if left > 0:
21:24:19.205280 line        16         if right > left:
21:24:19.205280 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 0
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '((()))'
21:24:19.205280 call         9     def gen(self, sub, left, right):
21:24:19.205280 line        10         if left == 0 and right == 0:
21:24:19.205280 line        11             self.res.append(sub)
21:24:19.205280 line        12             return
21:24:19.205280 return      12             return
Return value:.. None
21:24:19.205280 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.206278 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.206278 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.207278 line        16         if right > left:
21:24:19.207278 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 1
Starting var:.. right = 2
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(()'
21:24:19.207278 call         9     def gen(self, sub, left, right):
21:24:19.207278 line        10         if left == 0 and right == 0:
21:24:19.207278 line        14         if left > 0:
21:24:19.208277 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 0
Starting var:.. right = 2
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(()('
21:24:19.208277 call         9     def gen(self, sub, left, right):
21:24:19.209282 line        10         if left == 0 and right == 0:
21:24:19.209282 line        14         if left > 0:
21:24:19.209282 line        16         if right > left:
21:24:19.209282 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(()()'
21:24:19.209282 call         9     def gen(self, sub, left, right):
21:24:19.209282 line        10         if left == 0 and right == 0:
21:24:19.210275 line        14         if left > 0:
21:24:19.210275 line        16         if right > left:
21:24:19.210275 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 0
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(()())'
21:24:19.210275 call         9     def gen(self, sub, left, right):
21:24:19.210275 line        10         if left == 0 and right == 0:
21:24:19.210275 line        11             self.res.append(sub)
21:24:19.210275 line        12             return
21:24:19.210275 return      12             return
Return value:.. None
21:24:19.210275 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.211275 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.211275 line        16         if right > left:
21:24:19.211275 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 1
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(())'
21:24:19.211275 call         9     def gen(self, sub, left, right):
21:24:19.211275 line        10         if left == 0 and right == 0:
21:24:19.211275 line        14         if left > 0:
21:24:19.211275 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 0
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(())('
21:24:19.212275 call         9     def gen(self, sub, left, right):
21:24:19.212275 line        10         if left == 0 and right == 0:
21:24:19.212275 line        14         if left > 0:
21:24:19.212275 line        16         if right > left:
21:24:19.212275 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 0
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '(())()'
21:24:19.212275 call         9     def gen(self, sub, left, right):
21:24:19.212275 line        10         if left == 0 and right == 0:
21:24:19.214273 line        11             self.res.append(sub)
21:24:19.214273 line        12             return
21:24:19.214273 return      12             return
Return value:.. None
21:24:19.215273 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.215273 line        16         if right > left:
21:24:19.215273 return      16         if right > left:
Return value:.. None
21:24:19.215273 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.215273 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.216273 line        16         if right > left:
21:24:19.216273 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 2
Starting var:.. right = 2
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()'
21:24:19.216273 call         9     def gen(self, sub, left, right):
21:24:19.216273 line        10         if left == 0 and right == 0:
21:24:19.217273 line        14         if left > 0:
21:24:19.217273 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 1
Starting var:.. right = 2
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()('
21:24:19.217273 call         9     def gen(self, sub, left, right):
21:24:19.217273 line        10         if left == 0 and right == 0:
21:24:19.218271 line        14         if left > 0:
21:24:19.218271 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 0
Starting var:.. right = 2
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()(('
21:24:19.227267 call         9     def gen(self, sub, left, right):
21:24:19.227267 line        10         if left == 0 and right == 0:
21:24:19.228265 line        14         if left > 0:
21:24:19.228265 line        16         if right > left:
21:24:19.228265 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()(()'
21:24:19.228265 call         9     def gen(self, sub, left, right):
21:24:19.228265 line        10         if left == 0 and right == 0:
21:24:19.228265 line        14         if left > 0:
21:24:19.229264 line        16         if right > left:
21:24:19.229264 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 0
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()(())'
21:24:19.229264 call         9     def gen(self, sub, left, right):
21:24:19.229264 line        10         if left == 0 and right == 0:
21:24:19.229264 line        11             self.res.append(sub)
21:24:19.229264 line        12             return
21:24:19.230264 return      12             return
Return value:.. None
21:24:19.232263 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.233262 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.233262 line        16         if right > left:
21:24:19.233262 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 1
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()()'
21:24:19.233262 call         9     def gen(self, sub, left, right):
21:24:19.235261 line        10         if left == 0 and right == 0:
21:24:19.235261 line        14         if left > 0:
21:24:19.235261 line        15             self.gen(sub+'(', left-1, right)
Starting var:.. left = 0
Starting var:.. right = 1
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()()('
21:24:19.235261 call         9     def gen(self, sub, left, right):
21:24:19.235261 line        10         if left == 0 and right == 0:
21:24:19.235261 line        14         if left > 0:
21:24:19.235261 line        16         if right > left:
21:24:19.235261 line        17             self.gen(sub+')', left, right-1)
Starting var:.. left = 0
Starting var:.. right = 0
Starting var:.. self = <__main__.Solution object at 0x0000014A63D8D668>
Starting var:.. sub = '()()()'
21:24:19.236261 call         9     def gen(self, sub, left, right):
21:24:19.236261 line        10         if left == 0 and right == 0:
21:24:19.236261 line        11             self.res.append(sub)
21:24:19.237260 line        12             return
21:24:19.237260 return      12             return
Return value:.. None
21:24:19.237260 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.237260 line        16         if right > left:
21:24:19.237260 return      16         if right > left:
Return value:.. None
21:24:19.237260 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.238259 line        16         if right > left:
21:24:19.238259 return      16         if right > left:
Return value:.. None
21:24:19.238259 return      17             self.gen(sub+')', left, right-1)
Return value:.. None
21:24:19.238259 line        16         if right > left:
21:24:19.238259 return      16         if right > left:
Return value:.. None





['((()))', '(()())', '(())()', '()(())', '()()()']
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章