Skip to content

22.generate parentheses#2

Merged
wf9a5m75 merged 4 commits intomainfrom
neetcode/22.generate-parentheses
Sep 8, 2024
Merged

22.generate parentheses#2
wf9a5m75 merged 4 commits intomainfrom
neetcode/22.generate-parentheses

Conversation

@wf9a5m75
Copy link
Copy Markdown
Owner

@wf9a5m75 wf9a5m75 commented Jun 17, 2024

22. Generate Parentheses

level: Medium

https://leetcode.com/problems/generate-parentheses/


  • SWE協会に合わせて、lower_camel_case で変数名を定義
  • ロジックが分かりにくいので、大まかな動きをコメントで記載

@wf9a5m75 wf9a5m75 changed the title Neetcode/22.generate parentheses 22.generate parentheses Jun 18, 2024
class Solution:
def __init__(self):
self.parenthesis_cache: Dict[int, str] = {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

クラスメソッド間の空行は 1 行とすることをお勧めいたします。

https://google.github.io/styleguide/pyguide.html#35-blank-lines

Method definitions inside a class are surrounded by a single blank line.

https://google.github.io/styleguide/pyguide.html

One blank line between method definitions and between the docstring of a class and the first method.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

分かりました。合わせます。

(((B))) + "" -> ["((()))"]
((C)(A)) + "" -> ["(()())"]
"""
if (n == 0):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

条件が複数行に渡る場合を除き条件文を () で囲わないことをお勧めいたします。

https://google.github.io/styleguide/pyguide.html#33-parentheses

Do not use them in return statements or conditional statements unless using parentheses for implied line continuation or to indicate a tuple.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。そこら辺、まだJSの癖が抜けず申し訳ないです。JSはないと動かないので。合わせます。


results: List[str] = []

for left_count in range(n):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left_count は自分なら num_left_parentheses と付けると思います。ただ、強く推奨するわけではありません。


for left_count in range(n):
for left_hand in self.generateParenthesis(left_count):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この空行は不自然に感じました。処理の切れ目等に入れるのであれば自然に感じられます。 for 文の直後は処理の切れ目ではないと思いますので、空行を入れないほうが良いと思います。

https://peps.python.org/pep-0008/#blank-lines

Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

分かりました。合わせます


right_count = n - 1 - left_count
for right_hand in self.generateParenthesis(right_count):
results.append(f"({left_hand})" + right_hand)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f 文字列と + による文字列結合を同時に使う点に違和感を感じました。計 4 つの文字列を結合していますので、 f 文字列で統一するとよいと思います。
results.append(f"({left_hand}){right_hand}")

ちなみに、
results.append(f"{left_hand}({right_hand})")
が必要ない理由はなぜでしょうか…?第一感分からなかったため質問しました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。

そこはちょっと悩みましたが、f""の中に全部入れたとき、なんとなく可読性が悪いと感じたから分けました。
私としては、何の部分文字列が組み合わさっているのか分かりやすくするのが重要だと思いますが、どうですか?

例えば、もう少し冗長的に書くなら、こうです。

results.append("".join([
  f"({left_hand})",
  right_hand
])

実際、SQLを生で生成しなければならないとき、こういう風にすることがあります

sql = f"select id, name, score from {table_name} where score >= {lower_bounds} and score < {upper_bounds}"

よりは、こちらの方が可読性が良いと私としては思います

sql = " ".join([
  "select",
  "id, name, score",
  f"from {table_name}",
  "where",
  f"score >= {lower_bounds} and",
  f"score < {upper_bounds}"
])

Python は"""が使えるので、敢えてこんなことはしませんが、意図としては、「アルゴリズムの意図として、left_handに対して()を付けたものにright_handを結合するということを明示するため」です。

趣味嗜好の範囲なので、多くの人がf""に全部入れたほうが良い、というのであれば、合わせます

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そこはちょっと悩みましたが、f""の中に全部入れたとき、なんとなく可読性が悪いと感じたから分けました。
私としては、何の部分文字列が組み合わさっているのか分かりやすくするのが重要だと思いますが、どうですか?

あくまで自分の感覚となりますが、
results.append(f"({left_hand})" + right_hand)

results.append("".join([
  f"({left_hand})",
  right_hand
])

も、第一感何をしようとしているのか分かりにくく感じました。自分の場合は、 + 一つまでで済むのであれば + で、そうでなければ f 文字列で、文字列の結合を行います。

余談となりますが、

実際、SQLを生で生成しなければならないとき、こういう風にすることがあります
sql = f"select id, name, score from {table_name} where score >= {lower_bounds} and score < {upper_bounds}"

SQL インジェクション回避のため、 SQL 文を生成する際は、プレースホルダーを使用するのがよいと思います。

@wf9a5m75 wf9a5m75 merged commit 6110325 into main Sep 8, 2024

class Solution:
def __init__(self):
self.parenthesis_cache: Dict[int, str] = {}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dict[int, List[str]]ですか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants