给你一个字符串 text
,请你返回满足下述条件的 不同 非空子字符串的数目:
- 可以写成某个字符串与其自身相连接的形式(即,可以写为
a + a
,其中a
是某个字符串)。
例如,abcabc
就是 abc
和它自身连接形成的。
示例 1:
输入:text = "abcabcabc" 输出:3 解释:3 个子字符串分别为 "abcabc","bcabca" 和 "cabcab" 。
示例 2:
输入:text = "leetcodeleetcode" 输出:2 解释:2 个子字符串为 "ee" 和 "leetcodeleetcode" 。
提示:
1 <= text.length <= 2000
text
只包含小写英文字母。
解题思路:
以oi形式给出
查看字符串左右的哈希就可以判断出字符串左右是否相等
unsigned long long Base = 3;
vector<unsigned long long> Hash;
long long idx(char c)
{
return c;
}
long long get_hash(string s)
{
Hash.push_back(0);
for(char c : s) Hash.push_back(Hash.back() * Base + idx(c));
}
si到sj的字符串的哈希值为
si - sj = Hash[j] - Hash[i-1] * prim[j-i+1];
代码:
#include <bits/stdc++.h>
using namespace std;
unsigned long long Base = 3;
vector<unsigned long long> Hash;
long long idx(char c)
{
return c;
}
long long get_hash(string s)
{
Hash.push_back(0);
for(char c : s) Hash.push_back(Hash.back() * Base + idx(c));
}
int main()
{
string s = "leetcodeleetcode";
get_hash(s);
set<string> res;
//si - sj = Hash[j] - Hash[i-1] * prim[j-i+1];
for(int i = 1;i <= s.size();++i)
{
for(int j = i+1;j <= s.size();j+=2)
{
int len = j - i + 1;
int x1,y1,x2,y2;
x1 = i;
y1 = i - 1 + len/2;
x2 = y1+1;
y2 = j;
long long left = Hash[y1] - Hash[x1-1] * pow(Base,y1-x1+1);
long long right = Hash[y2] - Hash[x2-1] * pow(Base,y2-x2+1);
if(left == right)
{
res.insert(s.substr(i-1,len));
}
}
}
cout << res.size();
return 0;
}