题目链接
思路:一次遍历
分析:
1.只需要统计以当前字符结尾的子串。
2.最后直接进行求和即可
例如 “zab”,假设用r表示以当前字符结尾的环绕子串个数,当当前字符为’z’时,我们找到一个子串,r= 1,当当前字符为’a’,我们发现和’z’是连续的,r直接加1得,r= 2,而总的子串就有1 + 2 = 3, 当当前字符为’b’和前面的"za"构成连环绕连续,r再加1,r= 3,而总的环绕子串就有1 + 2 + 3 = 6,共6个。
不过此时有个问题:假设当前字符结尾的字串,之前遍历有过和当前字符一样的字符作为结尾。并且此时长度没有之前的长,该如何处理?
举例:“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyaaaaaaabcdefghijklmnopqrstuvwxyz”
假设当前字符是第二个b,此时以b结尾的应该还是之前的ab,长度为2,此时字串长度为28,此时我们应该取大的,28,因为前面短的ba,包含在此时长的字串(abcdefghijklmnopqrstuvwxyzab)中了。
再假设,当前字符是第三个b,此时字串为ab,长度为2,没有之前的大,那么我们应该还是取之前的。
所以可以得到规律,每次只需要记录以当前字符结尾的,最长字符串的 长度。
最后再累加即可。
代码:
class Solution {
public int findSubstringInWraproundString(String p) {
if(p.length()==1){
return 1;
}
int res = 0;
int len = p.length();
int[] cnt = new int[26];
int count = 1;
for(int r=0;r
//判断是否符合要求的连续的子串
if(r>0 && ( (p.charAt(r-1)-'a'+1) % 26 == (p.charAt(r)-'a') % 26)){
count++;
}else{
//否则就从头开始,就是长度从1开始
count = 1;
}
//记录以当前字符结尾的最大子串的长度
cnt[p.charAt(r)-'a'] = Math.max(cnt[p.charAt(r)-'a'],count);
}
//计算答案
for(int c : cnt){
res += c;
}
return res;
}
}



