https://leetcode-cn.com/problems/repeated-dna-sequences/
思路一:非常直观的方法,逐一取长度为10的子串,通过哈希计数即可。复杂度
O
(
N
L
)
O(NL)
O(NL)。
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
vector<string> ans;
const int LEN=10;
int n=s.size();
if(n<LEN)
return ans;
unordered_map<string,int> cnt;
for(int i=0;i<=n-10;i++)
{
string tmp=s.substr(i,10);
if(++cnt[tmp]==2)
ans.push_back(tmp);
}
return ans;
}
};
思路二:把 A 、 C 、 G 、 T A、C、G、T A、C、G、T分别映射到数字 0 、 1 、 2 、 3 0、1、2、3 0、1、2、3,那么一个长度为10的子串可以用一个20bit的整数表示,不妨设 s [ i , i + 10 ) s[i,i+10) s[i,i+10)对应的整数值为 v a l val val,我们可以在 O ( 1 ) O(1) O(1)时间内计算出下一个子串对应的整数值: ( v a l & 0 x 3 f f f f ) < < 2 ∣ i n t V a l [ s i + 10 ] (val\&0x3ffff)<<2\ |\ intVal[s_{i+10}] (val&0x3ffff)<<2 ∣ intVal[si+10]。这样就省去了方法一中每次都要计算子串的开销,时间复杂度降低至 O ( N ) O(N) O(N)。
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
vector<string> ans;
const int LEN=10;
int n=s.size();
if(n<LEN)
return ans;
unordered_map<char,int> toInt={{'A',0},{'C',1},{'G',2},{'T',3}};
unordered_map<int,int> cnt;
int curVal=0;
for(int i=0;i<=8;i++)
curVal=(curVal<<2)|toInt[s[i]];
for(int i=9;i<n;i++)
{
curVal=((curVal&0X3ffff)<<2)|toInt[s[i]];
if(++cnt[curVal]==2)
ans.push_back(s.substr(i-10+1,10));
}
return ans;
}
private:
};