package q433 import "slices" func canMutate(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 mutation } func minMutation(startGene string, endGene string, bank []string) int { reachables := make([][]int, len(bank)) initial := []int{} target := -1 for i := range len(bank) - 1 { for j := i + 1; j < len(bank); j++ { if canMutate(bank[i], bank[j]) { reachables[i] = append(reachables[i], j) reachables[j] = append(reachables[j], i) } } } for i := range bank { if bank[i] == endGene { target = i } if canMutate(startGene, bank[i]) { if i == target { return 1 } initial = append(initial, i) } } if target == -1 { return -1 } type qElem struct { path []int } queue := make([]qElem, 0, len(initial)*2) for _, i := range initial { queue = append(queue, qElem{path: []int{i}}) } for ; len(queue) > 0; queue = queue[1:] { cur := queue[0].path last := cur[len(cur)-1] next := reachables[last] for _, n := range next { if n == target { return len(cur) + 1 } if slices.Contains(cur, n) { continue } queue = append(queue, qElem{path: append(cur, n)}) } } return -1 } var _ = minMutation