🍀环绕字符串中唯一的子字符串
描述:
# 把字符串 s 看作 "abcdefghijklmnopqrstuvwxyz" 的无限环绕字符串,所以 s 看起来是这样的:
"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...." 。
现在给定另一个字符串 p 。返回 s 中 不同 的 p 的 非空子串 的数量 。
示例 1:
输入:p = "a"
输出:1
解释:字符串 s 中只有 p 的一个 "a" 子字符。
示例 2:
输入:p = "cac"
输出:2
解释:字符串 s 中只有 p 的两个子串 ("a", "c") 。
示例 3:
输入:p = "zab"
输出:6
解释:在字符串 s 中有 p 的六个子串 ("z", "a", "b", "za", "ab", "zab") 。
提示:
1 <= p.length <= 105
p 由小写英文字母组成
思考:
已知目标字符串是abc..z环绕的字符串,求p在里面与之对应的子串的数,又因为s串是连续的,因此只用求p中连续子串的数目,也就是求前一个字母和后一个字母的关系,这就能立刻想到动态规划方法,判断两个字母是不是连续的,可以用后一个减去前一个是否等于1,是则是连续的,否则不是,(p[i-1]+1)%26 == p[i]%26,两边对26取模看是否相等。
实现:
class Solution {
public int findSubstringInWraproundString(String p) {
int[] dp = new int[26];
int count = 0;
for (int i = 0; i < p.length(); ++i) {
if (i > 0 && (p.charAt(i) - p.charAt(i - 1) + 26) % 26 == 1) { // 字符之差为 1 或 -25
++count;
} else {
count = 1;
}
dp[p.charAt(i) - 'a'] = Math.max(dp[p.charAt(i) - 'a'], count);
}
return Arrays.stream(dp).sum();
}
}
\