Skip to content

127. Word Ladder#19

Open
5103246 wants to merge 1 commit intomainfrom
127-word-ladder
Open

127. Word Ladder#19
5103246 wants to merge 1 commit intomainfrom
127-word-ladder

Conversation

@5103246
Copy link
Copy Markdown
Owner

@5103246 5103246 commented Oct 3, 2025

- https://github.com/irohafternoon/LeetCode/pull/22/files
- アルファベットを使う方法と、単語を前半と後半に分ける方法もやっていた。
- アルファベットを使う方法は結構読みやすく感じたが、文字の種類が増えると管理が大変そう。
- 前半と後半に分ける方法はStep1の2つ目のコードと考えが似ている。前半と後半に分ける処理は関数にしたほうが読みやすいと感じた。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

基本的に考え方は同じだと思いますが、* などのワイルドカードを使うと文字列に * が入ってきたときに動かなくなるのが気になるという意見もありました。
tarinaihitori/leetcode#20 (comment)

Comment on lines +197 to +198
string pattern = candidate;
pattern[i] = kWildCardChar;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

BuildPatternToWordsのほうでも一文字をwildcardに変えるという処理が出てくるので関数化してしまってもよいかなと思いました

auto [candidate, distance] = candidate_and_distance.front();
candidate_and_distance.pop();

for (int i = 0; i < length; ++i) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

「全てのワードの長さが等しい」という前提の実装ですが、candidateの長さで回すほうが将来的にバグになりづらく良いかなと思いました

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.

その視点はなかったです。
ありがとうございます。

queue<pair<string, int>> candidate_and_level;
candidate_and_level.push({begin_word, 1});

while (!candidate_and_level.empty()) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ちょっと3重ループが深いので、分割できませんか。
たとえば、中の部分は、一文字違いを全部生成する、それぞれに対して、continue, return, push のどれかをするというコードですね。

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.

一文字違いのvectorを作成して、それぞれに対して処理を行うようにしてみました。
分割した方が、読みやすいですね。

class Solution {
public:
    int ladderLength(const string& begin_word, const string& end_word, const vector<string>& word_list) {
        set<string> available_words(word_list.begin(), word_list.end());
        set<string> seen_words{begin_word};
        queue<pair<string, int>> candidate_and_level;
        candidate_and_level.push({begin_word, 1});
        vector<string> neighbors;

        while (!candidate_and_level.empty()) {
            auto [candidate, level] = candidate_and_level.front();
            candidate_and_level.pop();

            neighbors.clear();
            BuildNeighbors(candidate, neighbors);

            for (const string& neighbor : neighbors) {
                if (seen_words.contains(neighbor)) {
                    continue;
                }
                if (!available_words.contains(neighbor)) {
                    continue;
                }
                if (neighbor == end_word) {
                    return level + 1;
                }
                candidate_and_level.push({neighbor, level + 1});
                seen_words.insert(neighbor);
            }
        }
        return 0;
    }
private:
    void BuildNeighbors(const string& word, vector<string>& neighbors) {
        for (int i = 0; i < word.size(); ++i) {
            string neighbor = word;
            for (char ch = 'a'; ch <= 'z'; ++ch) {
                neighbor[i] = ch;
                neighbors.push_back(neighbor);
            }
        }
    }
};

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