--- title: 【LeetCode】0022.Generate Parentheses date: 2023-02-15 is_modified: false disqus: cynthiahackmd categories: - "面試刷題" tags: - "LeetCode" --- {%hackmd @CynthiaChuang/Github-Page-Theme %} <br> Given `n` pairs of parentheses, write a function to generate all combinations of well-formed parentheses. <!--more--> <br> **Example 1:** ``` Input: n = 3 Output: ["((()))","(()())","(())()","()(())","()()()"] ``` <br> **Example 2:** ``` Input: n = 1 Output: ["()"] ``` <br> **Constraints**: - 1 <= n <= 8 <br> **Related Topics:** `String` `Dynamic Programming` `Backtracking` ## 解題邏輯與實作 好久沒刷 LeetCode,所以先拿之前寫過,但還沒打成網誌的題目來練練手。 這題會給定一個數字 n,以生成包含 n 個括號的所有正確形式。若要列出所有結果,我第一個想到的會是用遞迴,幾個中止條件也在第一時間就浮出來了: 1. **長度為 2n,且左括號(open parenthesis)個數等於右括號(close parenthesis)個數** 這個條件應該是可以輸出正確形式的中止條件,所以這個終止時需要回傳正確的形式。但實作時,我不想多傳入常數 n(因為這個數在遞迴過程中不會變),所以我把條件給反過來使用倒數的方式:「當左括號剩餘個數為零,且右括號剩餘個數亦為零」時終止。 2. **右括號剩餘個數少於左括號剩餘個數** 假設 n = 3,若目前字串為 `())` ,則左括號剩餘個數則為 2、右括號剩餘個數為 1,遇到這樣的非法形式就直接返回不處理了。 如果兩種終止條件都不滿足就繼續往下走: 1. 若左括號個數仍有剩餘,即不為 0,則輸出一左括號後繼續向下遞迴。 2. 若右括號剩餘個數大於左括號剩餘個數,則輸出一右括號後繼續向下遞迴。 有這些基本條件後就能開始寫 code 了,完整程式碼如下: ```python= class Solution: def generateParenthesis(self, n: int) -> List[str]: results = [] cur_str = "" self.generate(cur_str, n, n, results) return results def generate(self, cur_str: str, open_remaining: int, close_remaining: int, results:list): if open_remaining == 0 and close_remaining == 0: results.append(cur_str) return if close_remaining < open_remaining: return if open_remaining > 0: self.generate(cur_str + "(", open_remaining-1, close_remaining, results) if close_remaining > open_remaining: self.generate(cur_str + ")", open_remaining, close_remaining-1, results) ``` Runtime 大約 38 ms,約在 78.88% 左右,我再多加個終止條件試試應該可以加快速度: ```python= class Solution: def generateParenthesis(self, n: int) -> List[str]: results = [] cur_str = "" self.generate(cur_str, n, n, results) return results def generate(self, cur_str: str, open_remaining: int, close_remaining: int, results:list): if open_remaining == 0 and close_remaining == 0: results.append(cur_str) return if open_remaining == 0 and close_remaining > 0: cur_str += ')'*close_remaining results.append(cur_str) return if close_remaining < open_remaining: return if close_remaining < 0 or open_remaining < 0: return if open_remaining > 0: self.generate(cur_str + "(", open_remaining-1, close_remaining, results) if close_remaining > open_remaining: self.generate(cur_str + ")", open_remaining, close_remaining-1, results) ``` Runtime 有稍微提升來到了 31 ms,約在 95.25% 左右。 ## 其他連結 1. [【LeetCode】0000. 解題目錄](/LeetCode-0000-Contents) ## 更新紀錄 :::spoiler 最後更新日期:2023-02-15 - 2023-02-15 發布 - 2023-01-09 完稿 - 2023-01-09 起稿 ::: {%hackmd @CynthiaChuang/Github-Page-Footer %}