转载请声明地址 四元君
5058. 最长重复子串
题目难度 Hard
给出一个字符串 S,考虑其所有重复子串(S 的连续子串,出现两次或多次,可能会有重叠)。
返回任何具有最长可能长度的重复子串。(如果 S 不含重复子串,那么答案为 “”。)
示例 1:
输入:"banana"
输出:"ana"
示例 2:
输入:"abcd"
输出:""
提示:
2 <= S.length <= 10^5
S 由小写英文字母组成。
思路
这道题其实在牛客网上做过,但是使用那个方法,要么超出时间限制,要么超出内存限制…可见这道题的限制还是非常凶狠的。
先去除两个极端情况,比如"aaaaaaaaaaaaaaaaaaaaaaaaaa"这样的情况,真的很浪费时间,我们检索出这种情况然后直接交掉。接下来我们用额外的str来记录位置,这里要自定义一个排序的方法。要返回较长的那个字符串,否则直接排序下来的结果是空。
代码
class Solution {
public:
string compare(string &s, int a, int b) {
int i = a, j = b;
while (i < s.size() && j < s.size()) {
if (s[i] == s[j]) {
++i; ++j;
} else {
break;
}
}
return s.substr(a, i-a);
}
bool isSame(const string &s) {
for (int i = 0; i < s.size()-1; ++i) {
if (s[i] != s[i+1]) {
return false;
}
}
return true;
}
string longestDupSubstring(string S) {
if (isSame(S)) {
return S.substr(1);
}
vector<int> str;
for (int i = 0; i < S.size(); ++i) {
str.push_back(i);
}
sort(str.begin(), str.end(), [&](int a, int b){
int i = a, j = b;
while (i < S.size() && j < S.size()) {
if (S[i] < S[j]) {
return true;
} else if (S[i] > S[j]) {
return false;
}
++i; ++j;
}
return a > b;
});
string res;
for (int i = 0; i < str.size()-1; ++i) {
string temp = compare(S, str[i], str[i+1]);
if (temp.size() > res.size()) {
res = temp;
}
}
return res;
}
};