题目:
由于 string 作为 key 哈希需要 strcmp,所以性能不高,使用 int 看作 16 进制数,刚好一共 8 位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <cassert> #include <string> #include <vector> #include <unordered_map> #include <unordered_set> #include <queue>
using std::vector; using std::string; using std::unordered_map; using std::unordered_set; using std::queue;
#define GENE_LENGTH 8
class Solution { private: int gene_str2int(string gene) { int val = 0; int i, n = gene.size(); assert(n < 10); unordered_map<char, int> ch2int = { { 'A', 0x0 }, { 'C', 0x1 }, { 'T', 0x2 }, { 'G', 0x3 } }; for (i = 0; i < n; i++) { val |= ch2int[gene[i]] << i * 4; } return val; } vector<int> get_possible_neighbors(int gene_id) { vector<int> vec; int curr, next, neighbor; for (int i = 0; i < GENE_LENGTH; i++) { curr = (gene_id >> (4 * i)) & 0xF; for (int j = 1; j <= 3; j++) { next = (curr + j) % 4; neighbor = (gene_id & ~(0xF << (4 * i))) | (next << (4 * i)); vec.push_back(neighbor); } } return vec; }
public: int minMutation(string startGene, string endGene, vector<string> &bank) { unordered_set<int> bank_set; unordered_set<int> visited; vector<int> neighbors; queue<int> q; int i, gene_id, level = 0; int target_gene_id = gene_str2int(endGene);
for (string &gene : bank) { bank_set.insert(gene_str2int(gene)); }
q.push(gene_str2int(startGene));
while (!q.empty()) { int q_size = q.size(); for (i = 0; i < q_size; i++) { gene_id = q.front(); visited.insert(gene_id); q.pop(); if (gene_id == target_gene_id) { return level; } neighbors = get_possible_neighbors(gene_id); for (int &neighbor : neighbors) { if (bank_set.count(neighbor) && !visited.count(neighbor)) { q.push(neighbor); } } }
level++; } return -1; } };
|