环绕字符串中唯一的子串——动态规划

问题定义

把字符串 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();
    }
}
posted @ 2022-05-25 09:38  茶柒每天要学习  阅读(28)  评论(0编辑  收藏  举报