问题描述
我正在解决Leetcode 1044,答案是使用二进制搜索和滚动哈希。基本上使用二进制搜索来选择长度,然后搜索该长度的重复字符串。在这里,滚动散列发挥了作用,以节省空间(而不是使用集合存储所有子串,而是存储子串的散列)。这就是解决方案的背景。
我的问题是用于防止溢出的模数。我选择了Long.MAX_VALUE,我相信它足以应付它,但当我使用Long.MAX_VALUE时,答案是不正确的。但是,当我使用Long.MAX_VALUE / 26或Math.pow(2,32)时,它们都可以工作。抱歉,我对模数很不好,我想我肯定错过了一些事情。有人可以阐明它吗?谢谢!以下是我的解决方案:
public static long modulus = Long.MAX_VALUE / 26;
public String longestDupSubstring(String S) {
int n = S.length();
int l = 1;
int r = n - 1;
int index = -1;
while (l <= r) {
int m = l + (r - l) / 2;
int temp = findDuplicate(S,m);
if (temp != -1) {
index = temp;
l = m + 1;
}
else {
r = m - 1;
}
}
return index == -1 ? "" : S.substring(index,index + r);
}
private int findDuplicate(String s,int len) {
Set<Long> set = new HashSet<>();
long hash = 0;
long p = 1;
for (int i = 0; i < len; i++) {
hash = (hash * 26 + s.charAt(i) - 'a') % modulus;
p = (p * 26) % modulus;
}
set.add(hash);
for (int i = len; i < s.length(); i++) {
hash = (hash * 26 + (s.charAt(i) - 'a')
- (s.charAt(i - len) - 'a') * p) % modulus;
if (hash < 0) {
hash += modulus;
}
if (set.contains(hash)) {
return i - len + 1;
}
set.add(hash);
}
return -1;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)