1. 程式人生 > >433. Minimum Genetic Mutation

433. Minimum Genetic Mutation

col empty 找到 end urn multipl 更多 次數 task

問題描述:

A gene string can be represented by an 8-character long string, with choices from "A", "C", "G", "T".

Suppose we need to investigate about a mutation (mutation from "start" to "end"), where ONE mutation is defined as ONE single character changed in the gene string.

For example, "AACCGGTT" -> "AACCGGTA"

is 1 mutation.

Also, there is a given gene "bank", which records all the valid gene mutations. A gene must be in the bank to make it a valid gene string.

Now, given 3 things - start, end, bank, your task is to determine what is the minimum number of mutations needed to mutate from "start" to "end". If there is no such a mutation, return -1.

Note:

  1. Starting point is assumed to be valid, so it might not be included in the bank.
  2. If multiple mutations are needed, all mutations during in the sequence must be valid.
  3. You may assume start and end string is not the same.

Example 1:

start: "AACCGGTT"
end:   "AACCGGTA"
bank: ["AACCGGTA"]

return: 1

Example 2:

start: "AACCGGTT"
end:   "AAACGGTA"
bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]

return: 2

Example 3:

start: "AAAAACCC"
end:   "AACCCCCC"
bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"]

return: 3

解題思路:

這道題可以用bfs來解答,與word ladder十分相似。

不過這道題有更多的限制:

  1.gene從{‘A‘, ‘C‘, ‘G‘, ‘T‘ }中選擇。

  2.每一個mutation的結果必須在bank中能夠找到。

我們用queue來存儲當前的gene string,並且用另一個queue來存儲變化次數。

這兩個queue要保持同步。

在最開始可以首先檢查end是否在bank中,不在bank中的話,無論如何我們也到不達終點,可以直接返回-1.

在檢查當前字符串是否可以加入隊列時需要檢查:

  1. 是否已經訪問過

  2. 是否在bank中可以找到

代碼:

class Solution {
public:
    int minMutation(string start, string end, vector<string>& bank) {
        vector<char> genes = {A, T, C, G};
        unordered_set<string> s(bank.begin(), bank.end());
        
        if(s.count(end) == 0) return -1;
        
        unordered_set<string> visited;
        queue<string> q;
        queue<int> distance_q;
        q.push(start);
        distance_q.push(0);
        
        while(!q.empty()){
            string cur = q.front();
            q.pop();
            int dis = distance_q.front();
            distance_q.pop();
            for(int i = 0 ; i < 8; i++){
                for(int j = 0; j < 4; j++){
                    string temp = cur;
                    if(genes[j] == temp[i]) continue;
                    temp[i] = genes[j];
                    
                    if(temp == end) return dis+1;
                    if(visited.count(temp) == 0 && s.count(temp) != 0){
                        visited.insert(temp);
                        q.push(temp);
                        distance_q.push(dis+1);
                    }
                }
            }
        }
        return -1;
    }
};

433. Minimum Genetic Mutation