Conversation
| if n == 0: | ||
| return [] |
There was a problem hiding this comment.
この問題では不要ですが、どちらかというとsol3のように、[""]を返す方が正しそうな気がしますね。
| if n == 0: | ||
| return [] | ||
|
|
||
| parentheses = [] |
There was a problem hiding this comment.
parenthesisと見間違えそうです。parenthesisにも複数の括弧がありますし、意味もやや曖昧ですね。
There was a problem hiding this comment.
ご指摘の通りだと思います。
parenthesisはprefixに、parenthesesの方をresultsとしました。
| return | ||
| if left_used < n: | ||
| parenthesis += "(" | ||
| generate_parenthesis_from(parenthesis, left_used + 1, right_used) |
There was a problem hiding this comment.
sol1のようにparenthesis + "("としない理由はありますか?
There was a problem hiding this comment.
listで文字を貯めて、最後にjoinしたら良さそうですかね。現状は新しいstrオブジェクトを作り直しているだけの意図が不明な無駄な操作に見えます。
There was a problem hiding this comment.
やっと意図が分かりました。strはimmutableでしたね。
listに直した方が良さそうですので修正しました。
There was a problem hiding this comment.
文字列のコピーは割と速く、どうせ、このプログラムは n がカタラン数で増加するので20くらいがせいぜいでしょう。そう考えるとあまり大きな問題ではないかもしれません。どれくらい速くなっているかは計測してもいいでしょう。
There was a problem hiding this comment.
ほぼ変わらない、というかrevisedが遅い場合の方が遅かったです。答えの数が大きいことによってjoinを毎回行うオーバーヘッドが大きくなっていそうです。意外な結果でした。
| for i in range(n): | ||
| for A in self.generateParenthesis(i): | ||
| for B in self.generateParenthesis(n - 1 - i): | ||
| result.append("({}){}".format(A, B)) |
There was a problem hiding this comment.
f-stringの方が可読性が良さそうですね。こちらに書き換えました。
| class Solution: | ||
| @functools.cache | ||
| def generateParenthesis(self, n: int) -> List[str]: | ||
| # Valid parentheses must be written in the form of (A)B, where A and B are valid parentheses uniquely. |
There was a problem hiding this comment.
context-free grammarですね。
S -> (S)S | ε
There was a problem hiding this comment.
確かにそうですね。ただ、この問題では「一意に書ける」ことが重要なのではないかと思いました。
There was a problem hiding this comment.
すみません、「ただ」以降のつながりがよく分かりませんでした。単にCFGですねというコメントでした。
There was a problem hiding this comment.
なるほど、CFGであるか否かを意識するようにしようと思います。
There was a problem hiding this comment.
全ての有効な括弧列を生成でき、かつ、ambiguousではない文法なら、漏れなく重複なしで生成できますね。
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
parens = [[] for _ in range(n + 1)]
parens[0].append('')
for size in range(1, n + 1):
for inside_size in range(size):
right_size = size - inside_size - 1
for inside in parens[inside_size]:
for right in parens[right_size]:
parens[size].append(f'({inside}){right}')
return parens[n]There was a problem hiding this comment.
文字列操作の問題が出たときにCFGや正規表現、曖昧な言語かどうかは意識しようと思います。
このコードを見て気がつきましたが、この問題はカタラン数の漸化式が自然に連想されますね。
S -> (S)S | εの規則から答えの長さがカタラン数になることも分かりますね。
| return [] | ||
|
|
||
| parentheses = [] | ||
| frontier = [("(", 1, 0)] |
There was a problem hiding this comment.
たしかにその書き方もできますね。考えていませんでした。
https://leetcode.com/problems/generate-parentheses/description/