1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| class Solution { fun findLadders(beginWord: String, endWord: String, wordList: List<String>): List<List<String>> { val wordSet = wordList.toSet() if (!wordSet.contains(endWord)) return emptyList()
val graph = mutableMapOf<String, MutableSet<String>>() val found = bfs(beginWord, endWord, wordSet, graph) if (!found) return emptyList()
val result = mutableListOf<List<String>>() val path = mutableListOf(beginWord) dfs(beginWord, endWord, graph, path, result)
return result }
private fun bfs(beginWord: String, endWord: String, wordSet: Set<String>, graph: MutableMap<String, MutableSet<String>>): Boolean { val queue = java.util.ArrayDeque<String>() val visited = mutableSetOf<String>()
queue.add(beginWord) visited.add(beginWord)
var found = false val levelVisited = mutableSetOf<String>()
while (queue.isNotEmpty()) { val levelCount = queue.size repeat(levelCount) { val currentWord = queue.poll() val nextNodes = getNextLevelNodes(currentWord, wordSet) for (nextWord in nextNodes) { if (visited.contains(nextWord)) continue if (nextWord == endWord) { found = true } queue.add(nextWord) levelVisited.add(nextWord)
graph.getOrPut(currentWord, { mutableSetOf() }) .add(nextWord) } }
if (found) break
visited.addAll(levelVisited) levelVisited.clear() }
return found }
private fun dfs(beginWord: String, endWord: String, graph: Map<String, Set<String>>, path: MutableList<String>, result: MutableList<List<String>>) { if (beginWord == endWord) { result.add(path.toList()) return } if (!graph.containsKey(beginWord)) return
graph[beginWord]?.forEach { nextWord -> path.add(nextWord) dfs(nextWord, endWord, graph, path, result) path.removeAt(path.lastIndex) } }
private fun getNextLevelNodes(word: String, wordSet: Set<String>): Set<String> { val nodes = mutableSetOf<String>() val chars = word.toCharArray() for (i in chars.indices) { val oldChar = chars[i] for (j in 0 until 26) { val c = 'a' + j if (c == oldChar) continue chars[i] = c val next = String(chars) if (wordSet.contains(next)) { nodes.add(next) } } chars[i] = oldChar } return nodes } }
|