1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| class Solution { private static final int PRIME = Boolean.hashCode(true);
public String longestDupSubstring(String s) { long[] prefixHashArray = new long[s.length() + 1]; long[] factorArray = new long[s.length() + 1]; factorArray[0] = 1;
for (int i = 0; i < s.length(); i++) { prefixHashArray[i + 1] = prefixHashArray[i] * PRIME + s.charAt(i); factorArray[i + 1] = factorArray[i] * PRIME; }
String answer = "";
int left = 1, right = s.length(); while (left <= right) { int mid = (left + right) >>> 1; String subStr = findDupSubString(s, mid, prefixHashArray, factorArray); if (subStr.length() == mid) { left = mid + 1;
if (subStr.length() > answer.length()) { answer = subStr; } } else { right = mid - 1; } }
return answer; }
private String findDupSubString(String s, int length, long[] prefixHashArray, long[] factorArray) { Set<Long> set = new HashSet<>();
for (int i = 0; i <= s.length() - length; i++) { int j = i + length - 1;
long hash = prefixHashArray[j + 1] - prefixHashArray[i] * factorArray[length]; if (set.contains(hash)) { return s.substring(i, i + length); } else { set.add(hash); } }
return ""; } }
|
注意重复子串的长度最长可达 3 × 104 - 1,容易出现哈希冲突,所以使用了 long 型的数组存储前缀字符串的哈希值。
References
1044. Longest Duplicate Substring