时间轴

2025-11-23

init


题目:

由于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;
}
};