-
Notifications
You must be signed in to change notification settings - Fork 0
139. Word Break #8
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?
Conversation
| - cf. https://docs.python.org/ja/3.13/library/stdtypes.html#str.startswith | ||
| * https://github.com/fuga-98/arai60/blob/9e0b4995439f57158f4dc9aa4ad6ff7d1bb8d11a/139.%20Word%20Break.md | ||
| - DFSを使った解法 | ||
| - dequeの代わりに `list` を使っていて `pop()` を `-1` にしているので少し分かりづらいと思った |
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.
確認ですが、popと-1の違いはわかりますか。
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.
pop() は元のリストの末尾の要素を削除してからその要素を返し、-1(スライス)は元のリストを変更せずに元のリストの末尾の要素の浅いコピーを返す認識です。
.pop() を単純に [-1] に置き換えても正常に動かないですね。
申し訳ありません、私の勘違いでした。
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.
これは練習なのでどんどん間違えて大丈夫だと思います!
ここらへんを読むと良いかもしれません。
https://docs.python.org/ja/3.13/library/stdtypes.html#mutable-sequence-types
| if start_index == len(s): | ||
| return True | ||
|
|
||
| for end_index in range(start_index + 1, len(s) + 1): |
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.
len(s) + 1の+1は不要そうに見えます。末尾のindex はlen(s) - 1なので。
スライスは範囲外にアクセスしてもエラーを出さないです。
https://docs.python.org/ja/3.13/tutorial/introduction.html
| if not reachable[start_index]: | ||
| continue | ||
| for end_index in range(start_index + 1, s_size + 1): | ||
| if reachable[start_index] and s[start_index:end_index] in word_dict: |
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.
性質の違う条件はif文を分けたいと思いました。
| - cf. https://docs.python.org/ja/3.13/library/functools.html#functools.lru_cache | ||
| * 短絡評価で副作用のある関数(再帰)があって読みにくい | ||
| * `s` のスライスが分かりにくい | ||
| * ベースケース `i < 0` が直観的でない |
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.
コードないにコメントを入れてもいいのかなとお思いました。
| while start_index < len(s): | ||
| for word in wordDict: | ||
| end_index = start_index + len(word) | ||
| if s[start_index:end_index] == word: |
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.
スライスでコピーを毎回作っている点が気になりました。
if s.find(word, start_index, end_index) != -1:とも書けそうだなと思いました。どれくらい処理が軽くなるかは調べておりません。また、 find() をこの用途で使うのはあまり見ないとも思いました。
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.
startswith がありますね。
| def wordBreak(self, s: str, wordDict: List[str]) -> bool: | ||
| @cache | ||
| def can_break(i): | ||
| if i < 0: |
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.
負の場合にも True を返している点に違和感を感じました。
if i == 0:
return True
```
として、文字列の開始地点のみ True を返してあげるようにしたほうがシンプルだと思いました。| return True | ||
|
|
||
| for word in wordDict: | ||
| if s[i - len(word) + 1 : i + 1] == word and can_break(i - len(word)): |
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.
i - len(word) + 1 の部分が負になった場合の挙動が分かりにくく感じました。
>>> a = "0123456789"
>>> a[-2:5]
''
>>> a[-2:9]
'8'文字数が違うのでたまたま False になっているように感じました。
if i < len(word):
continueを入れてあげたほうが理解しやすくなると思いました。
| return True | ||
|
|
||
| for word in wordDict: | ||
| if s[i - len(word) + 1 : i + 1] == word and can_break(i - len(word)): |
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.
if s[i - len(word) + 1 : i + 1] == word:
return can_break(i - len(word))のほうがシンプルだと思いました。
| * `s` のスライスが分かりにくい | ||
| * ベースケース `i < 0` が直観的でない | ||
| * 実行時間: 7ms | ||
| - 大して変わらなかった |
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.
LeetCode の実行時間は計測誤差が大きいため、あまり信じすぎないほうがよいと思います。もしどうしても正確に実行時間を計測したい場合は、ローカルで複数回実行し、中央値を取ったほうがよいと思います。
また、実行時間を短くする必要がある場合は、 C++ 等のより高速な言語の仕様を検討することをお勧めいたします。
| class Solution: | ||
| def wordBreak(self, s: str, wordDict: List[str]) -> bool: | ||
| s_size = len(s) | ||
| reachable = [False] * (s_size + 1) |
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.
好みの問題かもしれません。
変数名から、中身の型が予測しづらいと感じました。
is_reachableはどうでしょうか?
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.
is_reachable は関数名にも見えるため、微妙なところです。 reachable で「到達可能かどうか?」というニュアンスがあるため、中に bool 値が含まれていると読み取れるとも思います。
139. Word Break
次回予告: 141. Linked List Cycle