127. Word Ladder#20
Conversation
| def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int: | ||
| def generate_patterns(word: str) -> Iterator[tuple[str, str]]: | ||
| for i in range(len(word)): | ||
| yield (word[:i], word[i + 1 :]) |
There was a problem hiding this comment.
配列のコピーで
O(L)分かかるので、
冒頭に述べられているオーダーはO(NL)ではなくてO(NL^2)になりませんか?
There was a problem hiding this comment.
確かにそうですね。
完全に抜けていました。
ご指摘ありがとうございます。
| difference_count += 1 | ||
| if difference_count > 1: | ||
| return False | ||
| return True |
There was a problem hiding this comment.
difference_count == 1
と書くと良いかもです。
全く同じ単語は問題には確かでないはず?かもしれませんが。
There was a problem hiding this comment.
レビューありがとうございます。
これは、difference_count == 1と書いた方が意図が明確になるという理由でしょうか?
一応、冒頭でs1 == s2のチェックはしているので、同じ単語がでても問題なく動くと思って実装しています。
| if beginWord in word_set: | ||
| word_set.remove(beginWord) |
There was a problem hiding this comment.
他の方のコードを読んでいるときに出てきたのですが、調べ忘れていました。
ご指摘ありがとうございます。
| frontier = deque([(beginWord, 1)]) | ||
| while frontier: | ||
| word, step = frontier.popleft() | ||
| if word == endWord: |
There was a problem hiding this comment.
ここで判定すると、到達する前にqueueに入っているワード全てについて探索が必要になるので、少し無駄があるかもしれません。
| for pattern in generate_patterns(word): | ||
| pattern_to_words[pattern].append(word) | ||
|
|
||
| frontier = deque([(beginWord, 1)]) |
There was a problem hiding this comment.
調べられているかもしれませんが、2つリストを用意して、stepが同じものを明示的に処理する方法もあります。その場合はdequeでなくてよく、またstepをタプルとしてdequeに入れる必要もなくなります。
There was a problem hiding this comment.
レビューありがとうございます。
(判定の箇所の変更も含めて)変更すると、以下のコードのようになりました。
個人的にこちらの方が挙動が分かりやすく、タプルのオーバーヘッドもないので良いと感じました。
frontier = [beginWord]
step = 0
while frontier:
step += 1
next_frontier = []
while frontier:
word = frontier.pop()
for pattern in generate_patterns(word):
for neighbor in pattern_to_words[pattern]:
if neighbor == endWord:
return step + 1
if neighbor in word_set:
word_set.remove(neighbor)
next_frontier.append(neighbor)
frontier = next_frontier
return 0| def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int: | ||
| def is_neighbor(s1: str, s2: str): | ||
| if len(s1) != len(s2): | ||
| raise ValueError("String must be of equl length.") |
There was a problem hiding this comment.
特に問題はないのですが、return Falseでもいいのかなと思いました。もし長さが違うものが紛れているのを例外にしたい場合は、最初にループで明示的に調べさせるなど、別の書き方をするかもしれません。
今回の問題
https://leetcode.com/problems/word-ladder/
次回の問題
https://leetcode.com/problems/maximum-depth-of-binary-tree/