Skip to content
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

Add 127. Word Ladder.md #20

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Add 127. Word Ladder.md #20

wants to merge 1 commit into from

Conversation

t0hsumi
Copy link
Owner

@t0hsumi t0hsumi commented Jan 30, 2025

return length + 1
if next_word in generated_words:
continue
generated_words.add(next_word)
Copy link

Choose a reason for hiding this comment

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

word_set から取り除くのも手かと思います。


先に1文字違いを調べておく方針。
1文字違いを調べるのに、time complexityがO(n^2 * m)かかり、
これはMemory limit exceededとなった。
Copy link

Choose a reason for hiding this comment

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

この問題、結構制限が適当に決められているという印象があります。
通らなかったらよくない解答である、通ったらよい解答である、というようには見ないほうがいいです。
いくつか選択があり、偶然にもこの場合はこういう制限がかかっていたので、そのうちのいくつかが偶然にも動かないものがあった。
とはいえ、どういうものが動かないかが分かったあとに、回避策がいくつかでてくるようにしておく事自体は大切です。

word, length = words_and_lengths.popleft()
for pattern in generate_pattern(word):
for next_word in pattern_to_words[pattern]:
if next_word == endWord:
Copy link

Choose a reason for hiding this comment

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

後のステップで直っていますが、ここのネストが深すぎてちょっと読みづらさを感じました。

Copy link
Owner Author

Choose a reason for hiding this comment

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

            for pattern in generate_pattern(word):
                for next_word in pattern_to_words[pattern]:

この二行圧縮すべきでしたね、ありがとうございます

for i in range(len_word):
if word1[i] == word2[i]:
continue
num_of_diffs += 1
Copy link

Choose a reason for hiding this comment

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

ここで、num_of_diffが2以上だったらループを抜けると無駄な処理を減らせそうです

generated_word = f"{word[:index]}{char}{word[index + 1:]}"
if generated_word not in word_set:
continue
yield generated_word

Choose a reason for hiding this comment

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

373-375 行目は、

if generated_word in word_set:
    yield generated_word

のほうが簡潔ではありませんか?

Copy link
Owner Author

Choose a reason for hiding this comment

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

個人的には、そこまで簡潔さが変わっている印象はないです。
こうしている理由としては、https://discord.com/channels/1084280443945353267/1192728121644945439/1194203372115464272
これに書いてある気持ちに近いかもしれません。

ただリンク先の問題と異なり、この部分は、条件も、それが成立した時・しなかった時にする処理も1行で表せるので、いただいた提案でも簡潔だと思います。

wordに対して、1文字違いをwordListから毎回探すやり方でTLE

find_words_diff_by_one()に時間がかかる。m = len(word), n = len(wordList)として、
find_words_diff_by_one()のtime complexityがO(mn).
Copy link

Choose a reason for hiding this comment

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

ladderLength() 全体の時間計算量も求めてみてください。そして、時間計算量を求めたあと、制約にあるデータサイズの上限を代入し、どれくらいの数字になるかを確かめてみてください。その数字が言語ごとの処理速度の違いを考慮したうえで、一定の数値以下に入っていれば、現実的な時間で処理が終わると思います。

今回の場合ですと O(m*n^2) とります。制約に 1 <= m <= 10、1 <= n <= 5000 とありますので、 m = 10、n = 5000 を代入します。すると 2.5 * 10^8 となります。 Python は比較的遅い言語で、 1 秒間に 100 万ステップくらいしか計算できません。2.5 * 10^8 / 10^6 = 250 となり、 250 秒くらいかかりそうということが分かります。これは制限時間を大きく超えそうです。

言語ごと速度の差は以下をご覧ください。
https://github.com/niklas-heer/speed-comparison
https://benchmarksgame-team.pages.debian.net/benchmarksgame/box-plot-summary-charts.html

上記の実行時間の概算方法は、 IPC やメモリのアクセスパターンや整数・浮動小数の計算速度の違い等、様々な要因で大きくぶれます。目安程度に考えることをお勧めいたします。


一番最後の、「visitedに追加される前に同じwordをnext_candidatesに加えている」によって
かなり遅くなっているみたいだった。BFSをするなら、最短経路以外の同じ地点に至るルートはできるだけ
早く探索対象から外した方が実行時間が短くなるようだった。
Copy link

Choose a reason for hiding this comment

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

LeetCode の実行環境は実行時間の計測の精度が良くないようです。 LeetCode に表示される実行時間はあまり信用しないほうがよいと思います。

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.

5 participants