思路
BFS模板
// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
Queue<Node> q; // 核⼼数据结构
Set<Node> visited; // 避免⾛回头路
q.offer(start); // 将起点加⼊队列
visited.add(start);
int step = 0; // 记录扩散的步数
while (q not empty) {
int sz = q.size();
/* 将当前队列中的所有节点向四周扩散 */
for (int i = 0; i < sz; i++) {
Node cur = q.poll();
/* 划重点:这⾥判断是否到达终点 */
if (cur is target)
return step;
/* 将 cur 的相邻节点加⼊队列 */
for (Node x : cur.adj())
if (x not in visited) {
q.offer(x);
visited.add(x);
}
}
/* 划重点:更新步数在这⾥ */
step++;
}
}
本题相当于将可选的路线已经给出bank
,我们所需要做的,就是替换start
每个下标位置处的值,看看是否能够组成bank中给出的路径set
,如果组成则加入到路径q
中,进行下一个下标位置的替换,知道找到end
为止
代码实现
class Solution {
public final char[] chars = new char[] {'A', 'C', 'G', 'T'};
// 采用BFS
public int minMutation(String start, String end, String[] bank) {
if(start.compareTo(end) == 0) return 0;
LinkedList<String> q = new LinkedList<>(); // 记录可选的下一步
Set<String> set = Arrays.stream(bank).collect(Collectors.toSet()); // 避免走重复的路
q.addLast(start);
int step = 0;
while(!q.isEmpty()) {
int size = q.size();
for(int i = 0; i < size; i++) {
String cur = q.pollFirst();
char[] curStr = cur.toCharArray();
// 遍历当前字符串,对其进行改变
for(int j = 0; j < curStr.length; j++) {
// 寻找与当前位置的字符不同的情况,能否使之改变成bank中的某一种
for(char c : chars) {
if(c != curStr[j]) {
// 组合成新的字符串
String newStr = cur.substring(0, j) + String.valueOf(c) + cur.substring(j + 1);
// 查看新组成的字符串在不在bank中,也即能不能做出当前种类的变换
if(set.contains(newStr)) {
// 如果可以,则判断这种变换是否使之成为了end,成为则step + 1
if(newStr.compareTo(end) == 0) {
return step + 1;
}
// 如果没有成为end,则在bank中将其去掉,因为已经有了这种变换
set.remove(newStr);
// 将当前变换加入到路径队列中
q.addLast(newStr);
}
}
}
}
}
step++;
}
return -1;
}
}