题目大意:给定一个DNA字符串由'A', 'T', 'C', 'G'表示,求长度为10的重复出现的DNA子串,要求不能使用系统或第三方的数据结构,时间复杂度要求为O(n)
题目分析:考虑到只有'A', 'T', 'C', 'G'四种核苷酸,因此可以用一个10位4进制数来唯一标识每个长度为10的DNA子串,这样最大的数字才4^10=1e6+,直接开个2e6的数组记录子串出现的次数,每次只要模一个4^10,从左往右依次记录,遇到出现过的输出即可。复杂度O(n)
样例输入:
TAGCTAATCAGCTAATCAGGTAGCTAATCAGGAACTG
样例输出:
AGCTAATCAG
TAGCTAATCA
GCTAATCAGG
#include <iostream>
#include <string>
using namespace std;
int const MAX = 2e6;
int const MOD = (1 << 20);
int mp[MAX];
string str;
int change(char s) {
if (s == 'A') {
return 0;
}
if (s == 'T') {
return 1;
}
if (s == 'C') {
return 2;
}
return 3;
}
int main() {
cin >> str;
int n = str.length();
int cur = 0;
for (int i = 0; i < 10; i ++) {
cur = cur * 4 + change(str[i]);
mp[cur] ++;
}
for (int i = 10; i < n; i ++) {
cur = cur * 4 + change(str[i]);
cur %= MOD;
if (mp[cur] == 1) {
for (int j = i - 9; j <= i; j ++) {
printf("%c", str[j]);
}
printf("\n");
}
mp[cur] ++;
}
}