-
Notifications
You must be signed in to change notification settings - Fork 0
Create 22. Generate Parentheses.md #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # 22. Generate Parentheses | ||
| ## STEP1 | ||
| - 何も見ずに解いてみる | ||
| - 単に再帰で () を至るところに挿入することを考えたが、重複して生成するのを防ぐ必要があり、set で管理すればできる。 | ||
| ```python | ||
| class Solution: | ||
| def generateParenthesis(self, n: int) -> List[str]: | ||
| if n <= 0: | ||
| raise ValueError("n must be positive.") | ||
| if n == 1: | ||
| return ["()"] | ||
|
|
||
| results = set() | ||
| for s in self.generateParenthesis(n - 1): | ||
| for i in range(len(s) + 1): | ||
| results.add(s[:i] + "()" + s[i:]) | ||
| return list(results) | ||
| ``` | ||
|
|
||
| - そもそも重複せずに発生する方法も書けるか? "(" の数と ")" の数を管理して書く。 | ||
| ```python | ||
| class Solution: | ||
| def generateParenthesis(self, n: int) -> List[str]: | ||
| if n <= 0: | ||
| raise ValueError("n must be positive.") | ||
|
|
||
| results = [] | ||
|
|
||
| def generate_helper(parentheses: str, num_open: int, num_close: int) -> None: | ||
| if num_open == 0 and num_close == 0: | ||
| results.append(parentheses) | ||
| return | ||
|
|
||
| if num_open == num_close: | ||
| generate_helper(parentheses + "(", num_open - 1, num_close) | ||
| return | ||
|
|
||
| if num_open > 0: | ||
| generate_helper(parentheses + "(", num_open - 1, num_close) | ||
| generate_helper(parentheses + ")", num_open, num_close - 1) | ||
|
|
||
| generate_helper("", n, n) | ||
| return results | ||
| ``` | ||
| - 上のコードは毎回新しい文字列を構築している。list を使って書き直す。 | ||
| - ついでに "(" の追加をまとめて書く。"(" が使える限りは必ず追加できる。"(" と ")" が同数の場合は ")" は追加できないので終了。 | ||
| ```python | ||
| class Solution: | ||
| def generateParenthesis(self, n: int) -> List[str]: | ||
| if n <= 0: | ||
| raise ValueError("n must be positive.") | ||
|
|
||
| results = [] | ||
|
|
||
| def generate_helper(parentheses: list[str], num_open: int, num_close: int) -> None: | ||
| if num_open == 0 and num_close == 0: | ||
| results.append("".join(parentheses)) | ||
| return | ||
|
|
||
| if num_open > 0: | ||
| parentheses.append("(") | ||
| generate_helper(parentheses, num_open - 1, num_close) | ||
| parentheses.pop() | ||
| if num_open == num_close: | ||
| return | ||
| parentheses.append(")") | ||
| generate_helper(parentheses, num_open, num_close - 1) | ||
| parentheses.pop() | ||
|
|
||
| generate_helper([""], n, n) | ||
| return results | ||
| ``` | ||
| - 手元で実行時間を計測したところ (10000 回の平均)、n = 8 で、文字列に追記する場合が 0.43 ms, list に追加する場合が 0.48 ms で、文字列に追記しても遅いわけではなかった。理由として、短い文字列であること、CPythonの場合は最適化される場合があること、が考えられるところでしょうか。 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 実測して検証しているのはよいと思います。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. そうですね。どの条件で最適化が起こるかは把握までできていません。 https://discord.com/channels/1084280443945353267/1200089668901937312/1210619083385479258
今後は list を使って join する書き方をすると思います。 |
||
|
|
||
| ## STEP2 | ||
| ### プルリクやドキュメントを参照 | ||
| - https://github.com/olsen-blue/Arai60/pull/54/files | ||
| - generate_helper([""], n, n) として括弧が両方 0 になれば終了か、generate_helper([""], 0, 0) として括弧が両方 n になれば終了かでは、前者の方が関数の処理が n に依存していないのでよいのではと思った。 | ||
| - https://github.com/shining-ai/leetcode/blob/main/arai60/50-53_Greedy_Backtracking/53_22_Generate%20Parentheses/rework.py | ||
| - num_open > 0 で "(" 追加、num_open < num_close: で ")" 追加という書き方もわかりやすいですね。 | ||
| ## STEP3 | ||
| ### 3回ミスなく書く | ||
| ```python | ||
| class Solution: | ||
| def generateParenthesis(self, n: int) -> List[str]: | ||
| if n <= 0: | ||
| raise ValueError("n must be positive.") | ||
|
|
||
| results = [] | ||
|
|
||
| def generate_helper(parentheses: str, num_open: int, num_close: int) -> None: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. num_open / num_close が、parentheses (引数) に含まれる parentheses の数ではなく、残り必要な数なのが気になりました。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. コメントありがとうございます。remaining などとした方がわかりやすいですね。 |
||
| if num_open == 0 and num_close == 0: | ||
| results.append(parentheses) | ||
| return | ||
| if num_open > 0: | ||
| generate_helper(parentheses + "(", num_open - 1, num_close) | ||
| if num_open < num_close: | ||
| generate_helper(parentheses + ")", num_open, num_close - 1) | ||
|
|
||
| generate_helper("", n, n) | ||
| return results | ||
| ``` | ||
|
|
||
| 3分,3分,2分で3回Accept | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
が 2 回登場するのが気になりました。 step3 で重複をなくせているのはとても良いと思います。