【力扣】最小基因变化

134 阅读1分钟

题目链接:leetcode-cn.com/problems/mi…

// start-end 每一次有效的基因变化后的基因序列 都是start->end的一个状态
//最短编辑距离的问题 抽象为边权为1的图上的最短路问题  使用BFS求解

//bank中的状态可以看作是图上的节点,因为需要保证 每次变化后的状态都在bank中
//两个状态如果只相差一个字符,说明这两个节点是相邻的
//从start出发,BFS逐层遍历图上的每一个节点,为了方便 直接将遍历完成的节点在bankSet删除即可
//第一次遍历到终点的时候,所花费的变化数一定是最小的(BFS中 肯定是层数越少 距离越短)
func minMutation(start string, end string, bank []string) int {
	//无需转换 次数为0
	if start == end {
		return 0
	}
	//将所有的bank中的序列存入map中 这一步只是便于查找,只会使用到key, value不重要
	bankSet := map[string]interface{}{}
	for _, s := range bank{
		bankSet[s] = nil
	}
	//end不是合法的基因序列
	if _, ok := bankSet[end]; !ok {
		return -1
	}
	//声明一个队列queue 存放当前节点的所有相邻节点
	queue := []string{start}
	for step := 0; queue != nil; step++ {
		//BFS 对当前节点进行BFS
		tmp := queue
		queue = nil
		for _, cur := range tmp {
			//找出当前节点的所有相连的边 和bank中只相差一个字符的字符串
			for index, x := range cur {
				for _, y := range "ACGT" {
					if x != y {
						after := cur[:index] + string(y) + cur[index+1:]
						if _, ok := bankSet[after]; ok {
							//找到了相邻的节点
							if after == end {
								return step + 1
							}
							//将已经遍历的节点删掉
							delete(bankSet, after)
							queue = append(queue, after)

						}
					}
				}
			}

		}

	}
	return -1
}