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