题目要求

思路一:BFS
- 找从 s t a r t start start状态到 e n d end end状态的最小步数;
- 用哈希表存每个状态和步数;
- 维护一个遍历队列,取队头元素 c u r cur cur,依次替换每一位得到下一个可能状态,合法(出现在bank中)即加入队列并更新步数;
- 直到下一个可能状态与 e n d end end相等,返回 s t e p + 1 step+1 step+1。
Java
class Solution {
static char[] items = new char[]{
'A', 'C', 'G', 'T'};
public int minMutation(String start, String end, String[] bank) {
Set<String> bankSet = new HashSet<>();
for(String s : bank)
bankSet.add(s);
Deque<String> que = new ArrayDeque<>();
Map<String, Integer> map = new HashMap<>();
que.addLast(start);
map.put(start, 0);
while(!que.isEmpty()) {
String cur = que.pollFirst();
char[] cs = cur.toCharArray();
int step = map.get(cur);
for(int i = 0; i < 8; i++) {
for(char c : items) {
if(cs[i] == c)
continue;
char[] clone = cs.clone();
clone[i] = c;
String nxt = String.valueOf(clone);
if(!bankSet.contains(nxt))
continue;
if(map.containsKey(nxt))
continue;
if(nxt.equals(end))
return step + 1;
map.put(nxt, step + 1);
que.addLast(nxt);
}
}
}
return -1;
}
}
- 时间复杂度: O ( C × n ) O(C\times n) O(C×n),其中 C = 32 = 8 × 4 C=32=8\times4 C=32=8×4,即四个基因分别替换八个位置
- 空间复杂度: O ( n ) O(n) O(n)
C++
static char items[4] = {
'A', 'C', 'G', 'T'};
class Solution {
public:
int minMutation(string start, string end, vector<string>& bank) {
queue<string> que;
unordered_map<string, int> map;
que.push(start);
map[start] = 0;
while(!que.empty()) {
string cur = que.front();
que.pop();
int step = map[cur];
for(int i = 0; i < 8; i++) {
for(char c :items) {
if(cur[i] == c)
continue;
string nxt = cur;
nxt[i] = c;
if(find(bank.begin(), bank.end(), nxt) == bank.end())
continue;
if(map.count(nxt))
continue;
if(nxt == end)
return step + 1;
map[nxt] = step + 1;
que.push(nxt);
}
}
}
return -1;
}
};
- 时间复杂度: O ( C × n ) O(C\times n) O(C×n),其中 C = 32 = 8 × 4 C=32=8\times4 C=32=8×4,即四个基因分别替换八个位置
- 空间复杂度: O ( n ) O(n)