环绕字符串中唯一的子串——动态规划
问题定义
把字符串 s 看作是 “abcdefghijklmnopqrstuvwxyz” 的无限环绕字符串,所以 s 看起来是这样的:
"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...." .
现在给定另一个字符串 p 。返回 s 中 唯一 的 p 的 非空子串 的数量 。
求解思路
利用字符串s是环绕字符串的特点,即在此类型字符串中,对于某个子串,只要知道第一个字符或最后一个字符和子串长度就能确定该子串。
利用该特点我们可以用动态规划求解。维护一个数组 \(dp[\alpha]\) 表示p中以\(\alpha\)结尾且在s中出现的子串的最大长度。
具体计算方法:
遍历字符串p时,维护连续递增子串长度k:初始化k=1,若\(p[i]\)是\(p[i-1]\)在s中的下一个字符,则令k+1,否则用k更新 \(dp[p[i]]\) 的最大值并令k=1继续遍历。
result = sum(dp)
代码:
点击查看代码
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) { // 字符之差为 1 或 -25
++k;
} else {
k = 1;
}
dp[p.charAt(i) - 'a'] = Math.max(dp[p.charAt(i) - 'a'], k);
}
return Arrays.stream(dp).sum();
}
}