1. 题目
所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。
在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来查找 DNA 分子中所有出现超过一次的 10 个字母长的序列(子串)。
示例:
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC", "CCCCCAAAAA"]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-dna-sequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
2.1 哈希
class Solution {
public:vector<string> findRepeatedDnaSequences(string s) {if(s.size() <= 10)return {};unordered_map<string,int> m;int i = 0;while(i < s.size()-9)m[s.substr(i++,10)]++;vector<string> ans;for(auto it = m.begin(); it != m.end(); ++it){if(it->second > 1)ans.push_back(it->first);}return ans;}
};
120 ms 23.1 MB
2.2 位运算
- 用0-3来表示四种字符,二进制只需要2位,总共20位即可表示10个字符
class Solution {
public:vector<string> findRepeatedDnaSequences(string s) {if(s.size() <= 10)return {};map<char,int> m = {{'A',0}, {'G',1}, {'C',2}, {'T',3}};unordered_map<int,int> c;int num = 0, i = 0, k=10;while(i < k-1){num <<= 2;num |= m[s[i++]];//生成前9位字符的二进制编码表示}vector<string> ans;while(i < s.size()){num = (num<<2)&~(3<<2*k);//num左移两位,3(11)移动20位,取反变成00,把出去的高位抹掉num |= m[s[i]];//加入后面进来的c[num]++;if(c[num]==2)//第二次出现,加入答案ans.push_back(s.substr(i-k+1,10));i++;}return ans;}
};
88 ms 14.9 MB