所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来查找目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。
示例:
输入:s = “AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT”
输出:[“AAAAACCCCC”, “CCCCCAAAAA”]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-dna-sequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
1. 最直接的思路就是将每个长度为10的子序列放入map之中,如果当前重复了,则将其放入结果数组之中,要注意第二次的重复的时候不需要放入结果数组之中;
2. 思路1中有重复的工作,比如在获取长度为10的字串的时候,并不是按照去掉最高位之后添加最低位来实现的,因此时间复杂度有优化的空间,同时如果能够将str映射为数字,也能够将map更改为int类型的数组,从而节约空间复杂度,要实现这个想法,基础是字符串中字符出现的可能性只有四个,从而长度为10的字符串的所有可能性为2^20,能够使用整形数组容纳,所以考虑使用二位二进制来分别表示四个字符,当需要右移的时候,则将当前的二进制数字左移两位,之后和新字符的二进制数组进行或运算,最后使用20位的掩码进行与运算,只保留低位即可。(复杂的点在于二进制与字符串之间的相互转换,但优化效果显著!!!)
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
unordered_map<string,int> smap;
vector<string> ret;
int len = s.size();
if(len<=10)return ret;
string temps = "";
for(int i = 0;i<len-9;i++)
{
temps = s.substr(i,10);
unordered_map<string,int>::iterator it = smap.find(temps);
if(it==smap.end())
{
smap.insert(pair<string,int>(temps,1));
}
else
{
if(it->second==1)
{
ret.push_back(temps);
it->second++;
}
}
}
return ret;
}
};
class Solution {
public:
int hmap[1048576] = {0};
string binaryToString(int binary)
{
char cmap[] = {'A','G','C','T'};
string ret = "";
for(int i = 0;i<10;i++)
{
char temp = cmap[binary%4];
ret = temp + ret;
binary = binary>>2;
}
return ret;
}
vector<string> findRepeatedDnaSequences(string s) {
vector<string> ret;
int len = s.size();
if(len<=10)return ret;
memset(hmap,0,1048575);
vector<int> charmap(128,0);
charmap['A'] = 0;
charmap['G'] = 1;
charmap['C'] = 2;
charmap['T'] = 3;
int temp_binary = 0;
for(int i = 0;i<10;i++)
{
temp_binary=temp_binary<<2;
temp_binary|=charmap[s[i]];
temp_binary&=0xfffff;
}
hmap[temp_binary]++;
for(int i = 10;i<len;i++)
{
temp_binary=temp_binary<<2;
temp_binary|=charmap[s[i]];
temp_binary&=0xfffff;
if(hmap[temp_binary]==0)
{
hmap[temp_binary]++;
}
else if(hmap[temp_binary]==1)
{
ret.push_back(binaryToString(temp_binary));
hmap[temp_binary]++;
}
}
return ret;
}
};