給你一個字符串 text ,請你返回滿足下述條件的 不同 非空子字符串的數目:這些子字符串可以寫成某個字符串與其自身的串聯。
示例 1:
輸入:text = "abcabcabc"
輸出:3
解釋:3 個子字符串分別爲 "abcabc" , "bcabca" 和 "cabcab" 。
示例 2:
輸入:text = "leetcodeleetcode"
輸出:2
解釋:2 個子字符串爲 "ee" 和 "leetcodeleetcode" 。
提示:
1 <= text.length <= 2000
text 只包含小寫英文字母。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/distinct-echo-substrings
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
const int N = 2020;
typedef unsigned long long ULL;
ULL power[N], h[N], base = 13111;
class Solution {
public:
void init(string text)
{
memset(power, 0, sizeof power);
memset(h, 0, sizeof h);
power[0] = 1;
int n = text.size();
for(int i = 1; i <= n; i++)
{
power[i] = power[i - 1] * base;
h[i] = h[i - 1] * base + text[i - 1];
}
}
ULL get(int l, int r)
{
return h[r] - h[l - 1] * power[r - l + 1];
}
int distinctEchoSubstrings(string text) {
int n = text.size();
unordered_map<string, string> mp;
init(text);
for(int len = 1; len * 2 <= n; len++)
{
for(int l = 1; l + len * 2 - 1 <= n; l++)
{
int l1 = l, r1 = l1 + len - 1;
int l2 = l1 + len, r2 = l2 + len - 1;
if(get(l1, r1) == get(l2, r2))
{
string sub = text.substr(l1, len);
if(!mp.count(sub)) mp[sub] = sub + sub;
}
}
}
//for(auto i : mp) cout << i.first << ' ' << i.second << endl;
return mp.size();
}
};