LeetCode 1044. Longest Duplicate Substring
作者:互联网
原题链接在这里:https://leetcode.com/problems/longest-duplicate-substring/
题目:
Given a string s
, consider all duplicated substrings: (contiguous) substrings of s that occur 2 or more times. The occurrences may overlap.
Return any duplicated substring that has the longest possible length. If s
does not have a duplicated substring, the answer is ""
.
Example 1:
Input: s = "banana" Output: "ana"
Example 2:
Input: s = "abcd" Output: ""
Constraints:
2 <= s.length <= 3 * 104
s
consists of lowercase English letters.
题解:
We could guess a length, and check if there is duplicate.
If there is, then we could guess a bigger one. Otherwise, a smaller one.
How to check duplicates with given length. Use rolling hash.
"abcd", len = 3. when "abc" we have a hash, when it comes to "d", first decrease "a" then add "d" hash.
Time Complexity: O(nlogn). n = s.length().
Space: O(n).
AC Java:
1 class Solution { 2 int m = 1000000007; 3 int base = 26; 4 5 public String longestDupSubstring(String s) { 6 if(s == null || s.length() == 0){ 7 return s; 8 } 9 10 int [] nums = new int[s.length()]; 11 for(int i = 0; i < s.length(); i++){ 12 nums[i] = (int)(s.charAt(i) - 'a'); 13 } 14 int l = 1; 15 int r = s.length(); 16 while(l <= r){ 17 int mid = l + (r - l) / 2; 18 if(isValid(s, mid, nums) != -1){ 19 l = mid + 1; 20 }else{ 21 r = mid - 1; 22 } 23 } 24 25 int start = isValid(s, l - 1, nums); 26 return s.substring(start, start + l - 1); 27 } 28 29 private int isValid(String s, int len, int [] nums){ 30 int n = s.length(); 31 Map<Long, List<Integer>> map = new HashMap<>(); 32 long hash = 0; 33 for(int i = 0; i < len; i++){ 34 hash = (hash * base + (s.charAt(i) - 'a')) % m; 35 } 36 37 map.put(hash, Arrays.asList(0)); 38 39 // pre-compute deduction multiplier 40 long mul = 1; 41 for(int i = 0; i < len; i++){ 42 mul = (mul * base) % m; 43 } 44 45 for(int start = 1; start < n - len + 1; start++){ 46 hash = (hash * base - nums[start - 1] * mul % m + m) % m; 47 hash = (hash + nums[start + len - 1]) % m; 48 List<Integer> list = map.get(hash); 49 if(list != null){ 50 // There are equal hash before 51 String cur = s.substring(start, start + len); 52 for(int ind : list){ 53 if(s.substring(ind, ind + len).equals(cur)){ 54 return ind; 55 } 56 } 57 } 58 59 map.putIfAbsent(hash, new ArrayList<Integer>()); 60 map.get(hash).add(start); 61 } 62 63 return -1; 64 } 65 }
类似Longest Repeating Substring.
标签:substring,hash,int,length,len,Substring,start,Duplicate,Longest 来源: https://www.cnblogs.com/Dylan-Java-NYC/p/16560459.html