Leetcode1044最长重复子串关于模数的小问题

问题描述

我正在解决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 (将#修改为@)