思路
1、差异比较bank中的序列和start序列的差距,将每一位的差距记录到二进制数的位上,表示一个序列,统计这个数1的个数,就是差异程度,数字越大差异越大。
2、计算start和end的差异,将start这样0差异的序列加到上面的差异序列数组中。
3、bfs,如果差异程度之差等于1并且差异数位差异位1时,就入队等待bfs。
4、细节,入队的数标记入队,不再能入队;记录每一层的入队数量,一层遍历完,res(结果)加1,如果当前的差异为0,说明bfs到start。
start = “AACCGGTT”, end = “AACCGGTA”, bank = [“AACCGGTA”]
start:AACCGGTT
end: AACCGGTA
bit: 00000001
转化为二进制数为1,差异程度为1(因为只有一个1)
代码
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
| class Solution { public: struct Gap{ int num; int n; }; int getBits_one(int x){ int res=0; while(x){ if(x&1) res++; x>>=1; } return res; } int calGap(string origin,string after){ int n=origin.length(); int gap=0; for(int i=0;i<n;i++) if(origin[i]!=after[i]) gap |= 1<<(n-i-1); return gap; } int bfs(Gap gap,const vector<Gap>& banks){ vector<bool> isPush(512); bool flag=false; int n=banks.size(); queue<Gap> p; p.push(gap); isPush[gap.num]=true; int res=-1; int thePush=1; int thePop=0; int cnt=0; while(!p.empty()&&!flag){ Gap k=p.front(); p.pop(); thePop++; for(int i=0;i<n;i++){ Gap t=banks[i]; if(!isPush[t.num]&&abs(k.n-t.n)==1&&getBits_one((k.num|t.num)-(k.num&t.num))==1){ isPush[t.num]=true; p.push(t); cnt++; } } if(thePop==thePush){ thePush=cnt; cnt=0; thePop=0; res++; } if(k.num==0) break; } return res; } int minMutation(string start, string end, vector<string>& bank) { int n=bank.size(); vector<Gap> banks(n+1); for(int i=0;i<n;i++){ string s=bank[i]; banks[i].num=calGap(start,s); banks[i].n=getBits_one(banks[i].num); } banks[n]=Gap{0,0}; Gap p; p.num=calGap(start,end); p.n=getBits_one(p.num); bool isInBank=false; for(int i=0;i<n+1;i++){ if(p.num==banks[i].num){ isInBank=true; break; } } if(!isInBank) return -1; int step=bfs(p,banks); return step==0?-1:step; } };
|