【哈希表+滑动窗口】这个没啥说的,就是十个十个地切割字符串,放进HashMap中统计出现的次数,需要注意,for循环的终止条件是i <= n - 10; 另外在统计的过程中就可以直接判断当前的出现次数。
class Solution {
// 哈希表 + 滑动窗口
// 3:21 4
public List<String> findRepeatedDnaSequences(String s) {
Map<String, Integer> map = new HashMap();
List<String> ans = new ArrayList();
int n = s.length();
for (int i = 0; i <= n - 10; i++) {
String str = s.substring(i, i + 10);
map.put(str, map.getOrDefault(str, 0) + 1);
if (map.get(str) == 2) {
ans.add(str);
}
}
return ans;
}
}
【字符串哈希】用哈希表如果以String为key的话,每次需要计算String的长度次,所以刚才不是严格意义上的O(n),但是我们可以在O(n)的时间复杂度内提前算好字符串的哈希值,这就是字符串哈希。
class Solution {
// 字符串哈希
// 3:24 5
public List<String> findRepeatedDnaSequences(String s) {
Map<Integer, Integer> map = new HashMap();
List<String> ans = new ArrayList();
int n = s.length(), x = 13331;
int[] h = new int[n + 1], p = new int[n + 1];
p[0] = 1;
for (int i = 1; i <= n; i++) {
h[i] = h[i - 1] * x + s.charAt(i - 1);
p[i] = p[i - 1] * x;
}
for (int i = 0; i <= n - 10; i++) {
int hs = h[i + 10] - h[i] * p[10];
map.put(hs, map.getOrDefault(hs, 0) + 1);
if (map.get(hs) == 2) ans.add(s.substring(i, i + 10));
}
return ans;
}
}