|
8 | 8 | import java.util.List; |
9 | 9 | import java.util.Set; |
10 | 10 |
|
| 11 | +@SuppressWarnings("unchecked") |
11 | 12 | public class Solution { |
12 | | - private final int mod = (int) 1e9 + 7; |
| 13 | + private static final int MOD = (int) 1e9 + 7; |
13 | 14 | private long[] hsh; |
14 | 15 | private long[] pw; |
15 | 16 | private final List[] cnt = new List[26]; |
16 | 17 |
|
17 | 18 | public String longestDupSubstring(String s) { |
18 | | - int n = s.length(), base = 131; |
19 | | - for (int i = 0; i < 26; i++) cnt[i] = new ArrayList<>(); |
| 19 | + int n = s.length(); |
| 20 | + int base = 131; |
| 21 | + for (int i = 0; i < 26; i++) { |
| 22 | + cnt[i] = new ArrayList<>(); |
| 23 | + } |
20 | 24 | hsh = new long[n + 1]; |
21 | 25 | pw = new long[n + 1]; |
22 | 26 | pw[0] = 1; |
23 | 27 | for (int j = 1; j <= n; j++) { |
24 | | - hsh[j] = (hsh[j - 1] * base + s.charAt(j - 1)) % mod; |
25 | | - pw[j] = pw[j - 1] * base % mod; |
| 28 | + hsh[j] = (hsh[j - 1] * base + s.charAt(j - 1)) % MOD; |
| 29 | + pw[j] = pw[j - 1] * base % MOD; |
26 | 30 | cnt[s.charAt(j - 1) - 'a'].add(j - 1); |
27 | 31 | } |
28 | 32 | String ans = ""; |
29 | 33 | for (int i = 0; i < 26; i++) { |
30 | | - if (cnt[i].size() == 0) { |
| 34 | + if (cnt[i].isEmpty()) { |
31 | 35 | continue; |
32 | 36 | } |
33 | 37 | List<Integer> idx = cnt[i]; |
34 | 38 | Set<Long> set; |
35 | | - int lo = 1, hi = n - idx.get(0); |
| 39 | + int lo = 1; |
| 40 | + int hi = n - idx.get(0); |
36 | 41 | while (lo <= hi) { |
37 | 42 | int len = (lo + hi) / 2; |
38 | 43 | set = new HashSet<>(); |
39 | 44 | boolean found = false; |
40 | 45 | for (int nxt : idx) { |
41 | | - if (nxt + len > n) { |
42 | | - break; |
43 | | - } |
44 | | - long substrHash = getSubstrHash(nxt, nxt + len); |
45 | | - if (set.contains(substrHash)) { |
46 | | - found = true; |
47 | | - if (len + 1 > ans.length()) { |
48 | | - ans = s.substring(nxt, nxt + len); |
| 46 | + if (nxt + len <= n) { |
| 47 | + long substrHash = getSubstrHash(nxt, nxt + len); |
| 48 | + if (set.contains(substrHash)) { |
| 49 | + found = true; |
| 50 | + if (len + 1 > ans.length()) { |
| 51 | + ans = s.substring(nxt, nxt + len); |
| 52 | + } |
| 53 | + break; |
49 | 54 | } |
50 | | - break; |
| 55 | + set.add(substrHash); |
51 | 56 | } |
52 | | - set.add(substrHash); |
53 | 57 | } |
54 | 58 | if (found) { |
55 | 59 | lo = len + 1; |
56 | | - } else hi = len - 1; |
| 60 | + } else { |
| 61 | + hi = len - 1; |
| 62 | + } |
57 | 63 | } |
58 | 64 | } |
59 | 65 | return ans; |
60 | 66 | } |
61 | 67 |
|
62 | 68 | private long getSubstrHash(int l, int r) { |
63 | | - return (hsh[r] - hsh[l] * pw[r - l] % mod + mod) % mod; |
| 69 | + return (hsh[r] - hsh[l] * pw[r - l] % MOD + MOD) % MOD; |
64 | 70 | } |
65 | 71 | } |
0 commit comments