Word Ladder II - LeetCode
Problem
- input:
- output:
Idea
Solution
```kotlin
import java.util.*
class Solution {
data class data(val begin: String, val path: MutableList<String>)
val diffMap = hashMapOf<String, Boolean>()
val connectMap = hashMapOf<String, MutableList<Int>>()
fun findLadders(beginWord: String, endWord: String, wordList: List<String>): MutableList<MutableList<String>> {
// 이어질 수 있는(차이 1) 문자 관계 미리 저장
for (i in wordList.indices) {
for (j in i +1 until wordList.size) {
if (cntDiff(wordList[i], wordList[j])) {
connectMap.getOrPut(wordList[i]){mutableListOf()}.add(j)
connectMap.getOrPut(wordList[j]){mutableListOf()}.add(i)
}
}
}
if (!connectMap.containsKey(beginWord)) {
for (idx in wordList.indices) {
if (cntDiff(beginWord, wordList[idx])) connectMap.getOrPut(beginWord){mutableListOf()}.add(idx)
}
}
var shortest = Int.MAX_VALUE // 최단 거리
val answer = mutableListOf<MutableList<String>>()
val queue = LinkedList<data>() // BFS seach용
val visited = hashMapOf<String, Boolean>() // 최단 거리이기 때문에 visited 하나로 공유 가능
queue.offerLast(data(beginWord, mutableListOf()))
while (queue.size > 0) {
val dt = queue.pollFirst()
visited[dt.begin] = true
if (dt.path.size > shortest) return answer // 더 이상 최단 거리와 같은 길이의 답이 나올 수 없음
// 목적지 도달
if (dt.begin == endWord) {
shortest = minOf(shortest, dt.path.size) // 최단거리 갱신
dt.path.add(0, beginWord) // path 저장
answer.add(dt.path)
continue
}
// 다음 탐색
for (idx in connectMap.getOrDefault(dt.begin, mutableListOf())) {
if (visited.containsKey(wordList[idx])) continue
val tmpp = dt.path.toMutableList()
tmpp.add(wordList[idx])
queue.offerLast(data(wordList[idx], tmpp))
}
}
return answer
}
// 두 문자의 차이가 1개인지 T/F 리턴
fun cntDiff(s: String, e: String): Boolean {
if (diffMap.containsKey("$s $e")) return diffMap["$s $e"]!! //memo
var cnt = 0
for (i in s.indices) {
if (s[i] != e[i]) cnt++
}
diffMap["$s $e"] = cnt == 1
diffMap["$e $s"] = cnt == 1
return cnt == 1
}
}
```
시간 복잡도:

Point