1. 程式人生 > >Leetcode 022 括號生成 思路詳解+反思易錯 Python實現

Leetcode 022 括號生成 思路詳解+反思易錯 Python實現

本人一直在努力地積累Leetcode上用Python實現的題,並且會盡力講清每道題的原理,絕不像其他某些部落格簡略地帶過。
如果覺得講的清楚,歡迎關注。


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

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

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

思路:首先我們必須要明確的是,要生成的括號一定是先以左括號開頭的,如果一開始不是左括號,生成的就不是我們想要的型別。所以這道題我們為了遍歷所有的加括號的情況,一定先生成左括號。分析示例,假設我們有3個左括號,3個右括號。比如說為了生成示例中的第一個,我們先新增儘可能多地新增左括號,然後在新增右括號。第二個,我們在生成了2個左括號後,加一個右括號,再加左括號。對比一下發現,與我們第一次連著新增三個左括號不同的是,第二次我們在添加了2個左括號後嘗試著去新增右括號。這就非常符合DFS的思想:先一條路一直從左走到黑(新增左括號),再回到上個路口的節點嘗試右邊的路(新增右括號),所以到目前思維就明確了。

class Solution:  
    # @param an integer  
    # @return a list of string 
    def generateParenthesis(self, n):
        res_list = []
        self.DFS(n, n, '', res)
        return res_list
        

    def DFS(self, left, right, s, res):
        if left == 0 and right == 0:
            res.append(s)
        else:
            if left > 0:
                self.DFS(left-1, right, s+'(', res)
            if right > left:
                self.DFS(left, right-1, s+')', res)
這道題整體程式碼邏輯非常清晰,主函式+遞迴函式, DFS的left , right 分別表示左右括號的剩餘數量,s表示目前製造的括號。高含金量的邏輯出現在DFS函式中的else部分。首先我們都知道base條件是左括號和右括號的數量都為0時。巧妙在於,我們的DFS一開始只會進入 if left > 0:裡的函式,第一次函式遞迴完畢返回後,還是停留在left = 1 , s='(('的狀況下,而且返回點在if left>0:下。接著它會進入right>left裡,進行一次遞迴後又會進入if left > 0:裡的遞迴函式。這就是DFS的魔力,它通過2個看起來平行的遞迴入口,通過程式碼順序製造遞迴的先後,最終達到了深度優先搜尋。