https://leetcode.cn/problems/minimum-genetic-mutation/description/?envType=study-plan-v2&envId=top-interview-150
思路:
根据题目的要求,每次对start改变后得到的字符串都应该在bank中,所以如果存在一条有效变化路径,bank中肯定存在一个状态与end只差一步(start也在bank中),同理我们这样推下去如果存在一个状态等于start就代表存在结果。
class Solution {
public int minMutation(String startGene, String endGene, String[] bank) {
// 判断endGene是否在bank中
boolean exist = false;
for (String s : bank) {
if(s.equals(endGene)) exist = true;
}
if(!exist) return -1;
// 存储所有状态和距离end的步数
HashMap<String, Integer> map = new HashMap<>();
map.put(endGene, 0);
map.put(startGene, -1);
for (String s : bank) {
map.put(s, -1); // -1表示未访问过
}
int cnt = 0;
// 存储与end差cnt步变化的状态
Queue<String> queue = new LinkedList<>();
queue.offer(endGene);
Queue<String> temp = new LinkedList<>();
while (!queue.isEmpty()) {
cnt++;
while (!queue.isEmpty()) {
String s = queue.poll();
for (String str : bank) {
// 如果str与s只差一个字符,并且这个状态未被访问过
if (map.get(str) == -1 && differ(str, s) == 1) {
if (str.equals(startGene)) {
return cnt;
}
map.put(str, cnt);
temp.offer(str);
}
}
// 不要忘记start状态
if (map.get(startGene) == -1 && differ(startGene, s) == 1) {
return cnt;
}
}
queue = temp;
temp = new LinkedList<>();
}
return -1;
}
/**
* 计算两个字符串之间的差异
* @param s 被计算串
* @param target 目标串
* @return 差异的字符数
*/
public int differ(String s, String target) {
int cnt = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != target.charAt(i)) {
cnt++;
}
}
return cnt;
}
public static void main(String[] args) {
System.out.println(new Solution().minMutation("AACCGGTT", "AACCGGTA", new String[]{}));
}
}