63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
package q127
|
|
|
|
// Ideas for improvement: use a hashmap to index strings instead of an O(n^2)
|
|
// comparison and neighbor matrix; use bidirectional BFS.
|
|
|
|
func reachable(a, b string) bool {
|
|
diff := false
|
|
for i := range len(a) {
|
|
if a[i] != b[i] {
|
|
if diff {
|
|
return false
|
|
}
|
|
diff = true
|
|
}
|
|
}
|
|
return diff // exactly one different char
|
|
}
|
|
|
|
func ladderLength(beginWord string, endWord string, wordList []string) int {
|
|
target := -1
|
|
neighbors := make([][]int, len(wordList))
|
|
|
|
for i := range wordList {
|
|
if target == -1 && wordList[i] == endWord {
|
|
target = i
|
|
}
|
|
for j := i + 1; j < len(wordList); j++ {
|
|
if reachable(wordList[i], wordList[j]) {
|
|
neighbors[i] = append(neighbors[i], j)
|
|
neighbors[j] = append(neighbors[j], i)
|
|
}
|
|
}
|
|
}
|
|
if target == -1 {
|
|
return 0
|
|
}
|
|
|
|
seen := make([]bool, len(wordList))
|
|
queue := make([][2]int, 0, len(wordList)) // index, steps
|
|
for i := range wordList {
|
|
if reachable(beginWord, wordList[i]) {
|
|
seen[i] = true
|
|
queue = append(queue, [2]int{i, 2})
|
|
}
|
|
}
|
|
for ; len(queue) > 0; queue = queue[1:] {
|
|
id, step := queue[0][0], queue[0][1]
|
|
if id == target {
|
|
return step
|
|
}
|
|
|
|
for _, n := range neighbors[id] {
|
|
if !seen[n] {
|
|
seen[n] = true
|
|
queue = append(queue, [2]int{n, step + 1})
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
var _ = ladderLength
|