题目
把字符串 s 看作是 abcdefghijklmnopqrstuvwxyz
的无限环绕字符串,所以 s 看起来是这样的:
...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....
现在给定另一个字符串 p 。返回 s 中 唯一 的 p 的 非空子串 的数量 。
样例
题意
- 求
无限环绕字符串
中某个子串
的子串
数量,如下图所示:
- 其中,
jklmnopqrstuvw
是已知条件,求得 该字符串的子串数量
解题思路
- 采用
动态规划
求解 - 对于两个以同一个字符结尾的子串,长的那个子串必然包含短的那个。如:
abc
和bc
都是以c
结尾,即,bc
是abc
的子串 - 我们可以定义
dp[α]
表示已知条件P
中以字符α
结尾且在 s 中的子串的最长长度,知道了最长长度,也就知道了不同的子串的个数。 - 那么如何计算
dp[α]
, 维护一个递增序列- 当前字符比上一个字符 相差刚好为 1 的时候,则 k++,否则,k = 1
- 再重新计算,
α
字符的子串个数
AC代码
class Solution {
public int findSubstringInWraproundString(String p) {
int[] dp = new int[26];
int k = 0;
for(int i = 0 ; i < p.length();i++){
if(i > 0 && (p.charAt(i) - p.charAt(i - 1) + 26) % 26 == 1){ // 维护一个递增序列
k++;
} else {
k = 1;
}
dp[p.charAt(i) - 'a'] = Math.max(dp[p.charAt(i) - 'a'],k);
}
return Arrays.stream(dp).sum();
}
}