因为只有四种核苷酸,所以用0,1,2,3分别表示四种核苷酸,那么每个核苷酸就可以用一个2位的二进制表示,所以我们可以将一个10个子母长的序列转化为一个20位的二进制序列。然后通过滑动窗口的方式扫描整个串。
代码:
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
unordered_map<char, int> m{{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}};
vector<string> ans;
unordered_map<int,int>smap;
int val = 0;
int mask = (1 << 20) - 1; //mask等于二进制的20个1
for (int i = 0; i < 10; ++i)
val = (val << 2) | m[s[i]];
smap[val]=1;
for(int i = 10; i < s.size(); ++i){
//注意这里要&mask,因为val是32位的,跟mask与就是取后面20位,相当于20位的前两位向左移位后变成了00
val = ((val << 2)&mask) | m[s[i]]; //去掉左移的一个字符再加上一个新字符
if(smap.find(val)==smap.end()){ //第一次出现
smap[val]=1;
}
else{
if(smap[val]==1){
ans.push_back(s.substr(i - 9, 10));
}
smap[val]++;
}
}
return ans;
}
};