LeetCode 1044. 最长重复子串(二分,哈希)
Posted live4m
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1044. 最长重复子串(二分,哈希)相关的知识,希望对你有一定的参考价值。
题意:
给出一个字符串 S,考虑其所有重复子串(S 的连续子串,出现两次或多次,可能会有重叠)。
返回任何具有最长可能长度的重复子串。(如果 S 不含重复子串,那么答案为 ""。)
数据范围:
2 <= S.length <= 10^5
S 由小写英文字母组成。
解法:
哈希预处理,
二分长度mid,用map存所有长度为mid的子串的哈希值出现的次数,
判断出现次数是否>=2即可check。
code:
/*
* @lc app=leetcode.cn id=1044 lang=cpp
*
* [1044] 最长重复子串
*/
// @lc code=start
string res;
const int maxm=1e5+5;
const int p=131;
#define ull unsigned long long
ull h[maxm];
ull base[maxm];
int n;
ull ask(int l,int r){
return h[r]-base[r-l+1]*h[l-1];
}
class Solution {
public:
bool check(int mid,string s){
if(!mid)return 1;
map<ull,int>mp;
for(int i=mid;i<=n;i++){
ull t=ask(i-mid+1,i);
mp[t]++;
if(mp[t]>=2){
res="";
for(int j=i-mid+1;j<=i;j++){
res+=s[j];
}
return 1;
}
}
return 0;
}
string longestDupSubstring(string s) {
n=s.size();
res="";
s="("+s;
base[0]=1;
h[0]=0;
for(int i=1;i<=n;i++){
h[i]=h[i-1]*p+s[i];
base[i]=base[i-1]*p;
}
int l=1,r=n;
int ans=0;
while(l<=r){
int mid=(l+r)/2;
if(check(mid,s)){
ans=mid,l=mid+1;
}else{
r=mid-1;
}
}
return res;
}
};
// @lc code=end
以上是关于LeetCode 1044. 最长重复子串(二分,哈希)的主要内容,如果未能解决你的问题,请参考以下文章
LC1044. Longest Duplicate Substring最长重复子串:二分答案 + 滚动哈希
LeetCode 686. 重复叠加字符串匹配 / 1044. 最长重复子串(字符串哈希) / 1705. 吃苹果的最大数目
LeetCode 686. 重复叠加字符串匹配 / 1044. 最长重复子串(字符串哈希) / 1705. 吃苹果的最大数目