思路比较简单
- 就是以基因序列为点,以找一个字母变一下为变。求点层数。
属于思路很定点的BFS题目,直接看完整注释就行
class Solution {
public int minMutation(String start, String end, String[] bank) {
//把基因库数组存入哈希表,以方便查找
Set<String> bankSet = new HashSet<String>(Arrays.asList(bank));
//用来记录一个基因,是从start 开始,变了多少步骤
Map<String,Integer> depthMap = new HashMap<>();
//记录一下子标准基因
char[] jiyins = {'A', 'C', 'G', 'T'};
//如果end不合法不在基因库直接返回
if(!bankSet.contains(end)){
return -1;
}
//广搜BFS需要使用队列
Queue<String> queue = new LinkedList<>();
//先把start放入队列中去
queue.add(start);
//执行BFS标准广搜
while (!queue.isEmpty()){
//队头出队,拿到一个当前基因
String oneJiyin = queue.poll();
//因为基因是8个字母,所以从每一个字母开始,向额外的三个字母开始扩展,变变化
//八个字母,所以循环8次,把每一个字母都尝试变一次
for(int i = 0; i < 8; i++){
//遍历合法基因字母,一共四个,去向着除了自己的那个,剩下的三个方向扩展
for(char jy : jiyins){
//在这里才转换数组,是因为每一次要使用新的值,这一次改变不能把原值替换掉,换过方向的要是新对象
char[] jiyinChars = oneJiyin.toCharArray();
if(jiyinChars[i] != jy){
//找到一个新的可替换的值,就进行替换
jiyinChars[i] = jy;
//然后入队列,并且保存深度。深度等于原深度+1
String newJiyin = new String(jiyinChars);
//如果新的基因,不在基因库里,则继续搜索,忽略这个新基因
if(!bankSet.contains(newJiyin)){
continue;
}
//如果基因深度记录器,已经有过这个新基因了,说明这个新基因出现过了,那就忽略这个新基因
if(depthMap.containsKey(newJiyin)){
continue;
}
queue.add(newJiyin);
depthMap.put(newJiyin,depthMap.getOrDefault(oneJiyin,0) + 1);
//如果这个新的基因就是end结果,那么返回其深度。也就是最终变化了多少次
if(newJiyin.equals(end)){
return depthMap.get(newJiyin);
}
}
}
}
}
//如果start无法转换成end 返回-1
return -1;
}
}