1062. Longest Repeating Substring (bs + rolling hash
T: O(nlogn)
S: O(n), set size
class Solution {
public int longestRepeatingSubstring(String s) {
int len = s.length();
int left = 0;
int right = len - 1;
while (left + 1 < right) {
int mid = left + (right - left)/2;
if (found(s, mid)) {
left = mid;
} else {
right = mid;
}
}
if (found(s, right)) { // right is longer, test first
return right;
}
if (found(s, left)) {
return left;
}
return 0;
}
private boolean found(String s, int len) {
long hash = 0L;
long base = 26L;
long mod = 100_000_007L;
Set<Long> set = new HashSet<>();
long powBaseLen = 1L;
for (int i = 0; i < len; i++) {
powBaseLen = (powBaseLen*base) % mod;
}
for (int i = 0; i < s.length(); i++) {
hash = (hash * base + (s.charAt(i) - 'a')) % mod;
if (i >= len) {
hash = (hash - (s.charAt(i-len) - 'a')*powBaseLen%mod + mod)%mod;
}
if (i >= len-1) { // sliding window has new value, 才要檢查 or 塞入 hash
if (set.contains(hash)) {
return true;
}
set.add(hash);
}
}
return false;
}
}
/*
slding window
xxx[abcd]exxx => cal hash
xxxa[bcde]xxx => cal new hash
1.
so add new hash with e
hash = (hash * base + (s.charAt(i) - 'a')) % mod;
2.
remove a
hash = (hash - (s.charAt(i-len) - 'a')*powBaseLen%mod + mod)%mod;
3.
when reach sliding window end, add hash, or check is it existed
if (i >= len-1) { // sliding window has new value, 才要檢查 or 塞入 hash
if (set.contains(hash)) {
return true;
}
set.add(hash);
}
*/
Last updated