题意
我们有一个串s,是由abcdefg…z循环连接而成的, 给出一个字符串p,求p得所有子串在s中出现的次数。
思路
最初的想法是用 d[i,j] 来表示:p中的第i位,是一个j连续的串的出现次数和,但是这样会算重,比如我们的”cac”,里面c会被重复统计两次。
那么,我们就需要考虑如何避免算重。
假如我们的p中同时包含“abcd”和”bcd”,考虑”abcd”的子串:a, b, c, d, ab, bc, cd, abc, bcd, abcd。再考虑”bcd”的子串:b, c, d, bc, cd, bcd。明显能够发现”bcd”的子串是属于”abcd”的子串的。即对于我们的每一个字母x,考虑以x结尾的连续字符串,只需要取最长的那一个来计算结果即可。
所以,我们用 d[i] 表示:以i结尾的满足条件的字符串的统计次数。最后的结果为a - z的累计值。
代码
class Solution {
public:
bool judge(char x, char y) {
return (y == x + 1 || x - y == 25);
}
int findSubstringInWraproundString(string p) {
int n = p.length();
if (n == 0) return 0;
vector<int> d(30, 0);
d[p[0] - 'a'] = 1;
int len = 1;
for (int i = 1; i < n; i++) {
if (judge(p[i - 1], p[i])) len++;
else len = 1;
d[p[i] - 'a'] = max(d[p[i] - 'a'], len);
}
int res = 0;
for (int i = 0; i < 26; i++) res += d[i];
return res;
}
};