1. 程式人生 > 其它 >環繞字串中唯一的子串——動態規劃

環繞字串中唯一的子串——動態規劃

問題定義

把字串 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();
    }
}