Skip to content

Commit f00f880

Browse files
committed
feat: add solutions to lc problem: No.1044
No.1044.Longest Duplicate Substring
1 parent 7468872 commit f00f880

File tree

6 files changed

+454
-4
lines changed

6 files changed

+454
-4
lines changed

solution/1000-1099/1044.Longest Duplicate Substring/README.md

+157-2
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,182 @@
3333
<li><code>S</code> 由小写英文字母组成。</li>
3434
</ol>
3535

36-
3736
## 解法
3837

3938
<!-- 这里可写通用的实现逻辑 -->
4039

40+
字符串哈希 + 二分查找。
41+
42+
字符串哈希用于计算字符串哈希值,快速判断两个字符串是否相等。二分枚举长度,找到满足条件的最大长度即可。
43+
4144
<!-- tabs:start -->
4245

4346
### **Python3**
4447

4548
<!-- 这里可写当前语言的特殊实现逻辑 -->
4649

4750
```python
48-
51+
class Solution:
52+
def longestDupSubstring(self, s: str) -> str:
53+
n = len(s)
54+
55+
def check(l):
56+
seen = set()
57+
for i in range(n - l + 1):
58+
t = s[i: i + l]
59+
if t in seen:
60+
return t
61+
seen.add(t)
62+
return ''
63+
64+
left, right = 0, n
65+
ans = ''
66+
while left < right:
67+
mid = (left + right + 1) >> 1
68+
t = check(mid)
69+
ans = t or ans
70+
if len(t) > 0:
71+
left = mid
72+
else:
73+
right = mid - 1
74+
return ans
4975
```
5076

5177
### **Java**
5278

5379
<!-- 这里可写当前语言的特殊实现逻辑 -->
5480

5581
```java
82+
class Solution {
83+
private long[] p;
84+
private long[] h;
85+
86+
public String longestDupSubstring(String s) {
87+
int base = 131;
88+
int n = s.length();
89+
p = new long[n + 10];
90+
h = new long[n + 10];
91+
p[0] = 1;
92+
for (int i = 0; i < n; ++i) {
93+
p[i + 1] = p[i] * base;
94+
h[i + 1] = h[i] * base + s.charAt(i);
95+
}
96+
String ans = "";
97+
int left = 0, right = n;
98+
while (left < right) {
99+
int mid = (left + right + 1) >> 1;
100+
String t = check(s, mid);
101+
ans = t.length() > ans.length() ? t : ans;
102+
if (t.length() > 0) {
103+
left = mid;
104+
} else {
105+
right = mid - 1;
106+
}
107+
}
108+
return ans;
109+
}
110+
111+
private String check(String s, int len) {
112+
int n = s.length();
113+
Set<Long> seen = new HashSet<>();
114+
for (int i = 1; i + len - 1 <= n; ++i) {
115+
int j = i + len - 1;
116+
long t = h[j] - h[i - 1] * p[j - i + 1];
117+
if (seen.contains(t)) {
118+
return s.substring(i - 1, j);
119+
}
120+
seen.add(t);
121+
}
122+
return "";
123+
}
124+
}
125+
```
126+
127+
### **C++**
128+
129+
```cpp
130+
typedef unsigned long long ULL;
131+
132+
class Solution {
133+
public:
134+
ULL p[30010];
135+
ULL h[30010];
136+
string longestDupSubstring(string s) {
137+
int base = 131, n = s.size();
138+
p[0] = 1;
139+
for (int i = 0; i < n; ++i)
140+
{
141+
p[i + 1] = p[i] * base;
142+
h[i + 1] = h[i] * base + s[i];
143+
}
144+
int left = 0, right = n;
145+
string ans = "";
146+
while (left < right)
147+
{
148+
int mid = (left + right + 1) >> 1;
149+
string t = check(s, mid);
150+
if (t.size() > ans.size()) ans = t;
151+
if (t.size() > 0) left = mid;
152+
else right = mid - 1;
153+
}
154+
return ans;
155+
}
156+
157+
string check(string s, int len) {
158+
int n = s.size();
159+
unordered_set<ULL> seen;
160+
for (int i = 1; i + len - 1 <= n; ++i)
161+
{
162+
int j = i + len - 1;
163+
ULL t = h[j] - h[i - 1] * p[j - i + 1];
164+
if (seen.count(t)) return s.substr(i - 1, len);
165+
seen.insert(t);
166+
}
167+
return "";
168+
}
169+
};
170+
```
56171

172+
### **Go**
173+
174+
```go
175+
func longestDupSubstring(s string) string {
176+
base, n := 131, len(s)
177+
p := make([]int64, n+10)
178+
h := make([]int64, n+10)
179+
p[0] = 1
180+
for i := 0; i < n; i++ {
181+
p[i+1] = p[i] * int64(base)
182+
h[i+1] = h[i]*int64(base) + int64(s[i])
183+
}
184+
check := func(l int) string {
185+
seen := make(map[int64]bool)
186+
for i := 1; i+l-1 <= n; i++ {
187+
j := i + l - 1
188+
t := h[j] - h[i-1]*p[j-i+1]
189+
if seen[t] {
190+
return s[i-1 : j]
191+
}
192+
seen[t] = true
193+
}
194+
return ""
195+
}
196+
left, right := 0, n
197+
ans := ""
198+
for left < right {
199+
mid := (left + right + 1) >> 1
200+
t := check(mid)
201+
if len(t) > len(ans) {
202+
ans = t
203+
}
204+
if len(t) > 0 {
205+
left = mid
206+
} else {
207+
right = mid - 1
208+
}
209+
}
210+
return ans
211+
}
57212
```
58213

59214
### **...**

solution/1000-1099/1044.Longest Duplicate Substring/README_EN.md

+153-2
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,172 @@
2424
<li><code>s</code> consists of lowercase English letters.</li>
2525
</ul>
2626

27-
2827
## Solutions
2928

3029
<!-- tabs:start -->
3130

3231
### **Python3**
3332

3433
```python
35-
34+
class Solution:
35+
def longestDupSubstring(self, s: str) -> str:
36+
n = len(s)
37+
38+
def check(l):
39+
seen = set()
40+
for i in range(n - l + 1):
41+
t = s[i: i + l]
42+
if t in seen:
43+
return t
44+
seen.add(t)
45+
return ''
46+
47+
left, right = 0, n
48+
ans = ''
49+
while left < right:
50+
mid = (left + right + 1) >> 1
51+
t = check(mid)
52+
ans = t or ans
53+
if len(t) > 0:
54+
left = mid
55+
else:
56+
right = mid - 1
57+
return ans
3658
```
3759

3860
### **Java**
3961

4062
```java
63+
class Solution {
64+
private long[] p;
65+
private long[] h;
66+
67+
public String longestDupSubstring(String s) {
68+
int base = 131;
69+
int n = s.length();
70+
p = new long[n + 10];
71+
h = new long[n + 10];
72+
p[0] = 1;
73+
for (int i = 0; i < n; ++i) {
74+
p[i + 1] = p[i] * base;
75+
h[i + 1] = h[i] * base + s.charAt(i);
76+
}
77+
String ans = "";
78+
int left = 0, right = n;
79+
while (left < right) {
80+
int mid = (left + right + 1) >> 1;
81+
String t = check(s, mid);
82+
ans = t.length() > ans.length() ? t : ans;
83+
if (t.length() > 0) {
84+
left = mid;
85+
} else {
86+
right = mid - 1;
87+
}
88+
}
89+
return ans;
90+
}
91+
92+
private String check(String s, int len) {
93+
int n = s.length();
94+
Set<Long> seen = new HashSet<>();
95+
for (int i = 1; i + len - 1 <= n; ++i) {
96+
int j = i + len - 1;
97+
long t = h[j] - h[i - 1] * p[j - i + 1];
98+
if (seen.contains(t)) {
99+
return s.substring(i - 1, j);
100+
}
101+
seen.add(t);
102+
}
103+
return "";
104+
}
105+
}
106+
```
107+
108+
### **C++**
109+
110+
```cpp
111+
typedef unsigned long long ULL;
112+
113+
class Solution {
114+
public:
115+
ULL p[30010];
116+
ULL h[30010];
117+
string longestDupSubstring(string s) {
118+
int base = 131, n = s.size();
119+
p[0] = 1;
120+
for (int i = 0; i < n; ++i)
121+
{
122+
p[i + 1] = p[i] * base;
123+
h[i + 1] = h[i] * base + s[i];
124+
}
125+
int left = 0, right = n;
126+
string ans = "";
127+
while (left < right)
128+
{
129+
int mid = (left + right + 1) >> 1;
130+
string t = check(s, mid);
131+
if (t.size() > ans.size()) ans = t;
132+
if (t.size() > 0) left = mid;
133+
else right = mid - 1;
134+
}
135+
return ans;
136+
}
137+
138+
string check(string s, int len) {
139+
int n = s.size();
140+
unordered_set<ULL> seen;
141+
for (int i = 1; i + len - 1 <= n; ++i)
142+
{
143+
int j = i + len - 1;
144+
ULL t = h[j] - h[i - 1] * p[j - i + 1];
145+
if (seen.count(t)) return s.substr(i - 1, len);
146+
seen.insert(t);
147+
}
148+
return "";
149+
}
150+
};
151+
```
41152

153+
### **Go**
154+
155+
```go
156+
func longestDupSubstring(s string) string {
157+
base, n := 131, len(s)
158+
p := make([]int64, n+10)
159+
h := make([]int64, n+10)
160+
p[0] = 1
161+
for i := 0; i < n; i++ {
162+
p[i+1] = p[i] * int64(base)
163+
h[i+1] = h[i]*int64(base) + int64(s[i])
164+
}
165+
check := func(l int) string {
166+
seen := make(map[int64]bool)
167+
for i := 1; i+l-1 <= n; i++ {
168+
j := i + l - 1
169+
t := h[j] - h[i-1]*p[j-i+1]
170+
if seen[t] {
171+
return s[i-1 : j]
172+
}
173+
seen[t] = true
174+
}
175+
return ""
176+
}
177+
left, right := 0, n
178+
ans := ""
179+
for left < right {
180+
mid := (left + right + 1) >> 1
181+
t := check(mid)
182+
if len(t) > len(ans) {
183+
ans = t
184+
}
185+
if len(t) > 0 {
186+
left = mid
187+
} else {
188+
right = mid - 1
189+
}
190+
}
191+
return ans
192+
}
42193
```
43194

44195
### **...**

0 commit comments

Comments
 (0)