- 题目描述
- 解题思路
- 代码(哈希表)
- 复杂度
- 代码
- 复杂度
力扣链接 题目描述
所有 DNA 都由一系列缩写为 'A','C','G' 和 ’T' 的核苷酸组成,例如:"ACGAATTCCG"。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来找出所有目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。
示例 1:
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" 输出:["AAAAACCCCC","CCCCCAAAAA"]
示例 2:
输入:s = "AAAAAAAAAAAAA" 输出:["AAAAAAAAAA"]
提示:
- 0 <= s.length <= 105
- s[i] 为 'A'、'C'、'G' 或 'T'
官方题解
- 哈希表
- 哈希表 + 滑动窗口 + 位运算
class Solution {
private static final int L = 10;
public List findRepeatedDnaSequences(String s) {
List res = new ArrayList<>();
Map map = new HashMap<>();
int len = s.length();
for (int i = 0; i < len - L + 1; ++i) {
String temp = s.substring(i, i + L);
map.put(temp, map.getOrDefault(temp, 0) + 1);
if (map.get(temp) == 2) {
res.add(temp);
}
}
return res;
}
}
复杂度
代码
static final int L = 10;
//滑动窗口+哈希表+位运算
Map bin = new HashMap() {{
put('A', 0);
put('C', 1);
put('G', 2);
put('T', 3);
}};
public List findRepeatedDnaSequences(String s) {
List res = new ArrayList<>();
int n = s.length();
//字符串长度小于10的肯定不存在重复的
if (n <= L) {
return res;
}
//用一个int类型的数的低20位表示10个2位的滑动窗口
int x = 0;
for (int i = 0; i < L - 1; ++i) {
//x << 2: x左移两位
//x = x | bin[ch]: 新字符进入窗口
x = (x << 2) | bin.get(s.charAt(i));
}
//使用map统计每10个字符转成int数的频次
Map map = new HashMap<>();
for (int i = 0; i <= n - L; ++i) {
//x = x & ((1 << 20) - 1): 窗口最左边的字符离开窗口,只保留低20位的内容
x = ((x << 2) | bin.get(s.charAt(i + L - 1))) & ((1 << (L * 2)) - 1);
map.put(x, map.getOrDefault(x, 0) + 1);
if (map.get(x) == 2) {
res.add(s.substring(i, i + L));
}
}
return res;
}
复杂度



