链接: https://leetcode-cn.com/problems/repeated-dna-sequences/
思路:
前缀字符串哈希:
一般用于比较两个字符串是否相等;使用该算法默认不会出现哈希冲突
将字符串看做P进制的数,P一般为131或13331;计算前缀子串hash存入数组h
使用前缀和计算区间子串的hash值然后使用HashMap进行判断是否出现多次
字符串计算后的结果会很大,可以使用MOD = 计算,使用long存储;在c++中可以使用unsigned long long, 溢出相当于取模
getOrDefault(key,default)
作用:如果存在相应的key则返回其对应的value,否则返回给定的默认值。返回的结果为key对应的value值
代码:
private int P = 13331;
private long MOD = Long.MAX_VALUE;
private static final int N = 100010;
private long[] p = new long[N];
private long[] h = new long[N];
public List<String> findRepeatedDnaSequences(String s) {
int len = s.length();
// 预处理
p[0] = 1;
for (int i = 1; i <= len; i++) {
p[i] = p[i - 1] * P;
h[i] = ((h[i - 1] * P) + s.charAt(i - 1)) % MOD; // hash
}
Map<Long, Integer> map = new HashMap<>();
List<String> res = new ArrayList<>();
for (int l = 1; l + 9 <= len; l ++) {
long hash = get(l, l + 9);
Integer orDefault = map.getOrDefault(hash, 0);
if (orDefault == 1) res.add(s.substring(l - 1, l + 9));
map.put(hash, orDefault + 1);
}
return res;
}
private long get(int l, int r) {
return h[r] - h[l - 1] * p[r - l + 1];
}