diff --git a/graph-bfs-dns/127.md b/graph-bfs-dns/127.md index 227c43f..73d7166 100644 --- a/graph-bfs-dns/127.md +++ b/graph-bfs-dns/127.md @@ -1,6 +1,112 @@ -- 問題: []() -- コメント集: [](https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/mobilebasic#h.o0jquy48e6cy) +- 問題: [127. Word Ladder](https://leetcode.com/problems/word-ladder/description/) +- コメント集: [127. Word Ladder](https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/mobilebasic#h.o0jquy48e6cy) + - [何かをしようとして、そのことを覚えておきながら別のことをしようとすると、覚えておかないといけないので混乱する](https://discord.com/channels/1084280443945353267/1233603535862628432/1290337478527422528) + - [名前空間](https://discord.com/channels/1084280443945353267/1201211204547383386/1215702126945112094) + - もう少し別関数に切り出した方がいい気もするし、25行程度に収まっているのでしない気もする + - [この問題、結構制限が適当に決められているという印象があります。...](https://discord.com/channels/1084280443945353267/1307605446538039337/1335074776338792512) + - 「どういうものが動かないかが分かったあとに、回避策がいくつかでてくるようにしておく事自体は大切」 --> その通りだと思った + - - 条件 + - 1 <= beginWord.length <= 10 + - endWord.length == beginWord.length + - 1 <= wordList.length <= 5000 + - wordList[i].length == beginWord.length + - beginWord, endWord, and wordList[i] consist of lowercase English letters. + - beginWord != endWord + - All the words in wordList are unique. - 方針1 -- 時間計算量: -- 空間計算量: + - 最短経路問題なのでBFSを使う + - beginword を一文字ずつアルファベット入れ替えて、合致するものが wordList にあればQueueにつめる + - 詰めたものを取り出してまた一文字ずつ入れ替える + - endword に合致したらその時点での深さ+1を返却する +- 時間計算量: O(N * word.length * 26) +- 空間計算量: O(N) + +## BFS +```java +class Solution { + + public int ladderLength(String beginWord, String endWord, List wordList) { + if (!wordList.contains(endWord)) { + return 0; + } + + Queue queue = new ArrayDeque<>(); + queue.add(new MiddleWordAndDepth(beginWord, 1)); + + while (!queue.isEmpty()) { + MiddleWordAndDepth middle = queue.poll(); + String middleWord = middle.middleWord; + int depth = middle.depth; + + for (int i = 0; i < middleWord.length(); i++) { + for (char c = 'a'; c <= 'z'; c++) { + String newWord = middleWord.substring(0, i) + c + middleWord.substring(i + 1); + + if (newWord.equals(endWord)) { + return depth + 1; + } + + if (wordList.contains(newWord)) { + queue.add(new MiddleWordAndDepth(newWord, depth + 1)); + } + } + } + } + + return 0; + } + + record MiddleWordAndDepth(String middleWord, int depth) {} +} +``` + +## BFS 2回目 +- 訪問済み管理を忘れたので無限ループで落ちた, hot がQueueに積まれ続けて無限ループ + ```shell + beginWord = "hot" + endWord = "dog" + wordList = ["hot","dog"] + ``` + +```java +class Solution { + + public int ladderLength(String beginWord, String endWord, List wordList) { + Set wordSet = new HashSet<>(wordList); + + if (!wordSet.contains(endWord)) { + return 0; + } + + Queue queue = new ArrayDeque<>(); + queue.add(new MiddleWordAndDepth(beginWord, 1)); + wordSet.remove(beginWord); + + while (!queue.isEmpty()) { + MiddleWordAndDepth middle = queue.poll(); + String middleWord = middle.middleWord; + int depth = middle.depth; + + for (int i = 0; i < middleWord.length(); i++) { + for (char c = 'a'; c <= 'z'; c++) { + String newWord = middleWord.substring(0, i) + c + middleWord.substring(i + 1); + + if (newWord.equals(endWord)) { + return depth + 1; + } + + if (wordSet.contains(newWord)) { + wordSet.remove(newWord); + queue.add(new MiddleWordAndDepth(newWord, depth + 1)); + } + } + } + } + + return 0; + } + + record MiddleWordAndDepth(String middleWord, int depth) {} +} +``` \ No newline at end of file