1. 程式人生 > >[LeetCode] Repeated Substring Pattern 重複子字串模式

[LeetCode] Repeated Substring Pattern 重複子字串模式

Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.

Example 1:

Input: "abab"

Output: True

Explanation: It's the substring "ab" twice.

Example 2:

Input: "aba"

Output: False

Example 3:

Input: "abcabcabcabc"

Output: True

Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)

這道題給了我們一個字串,問其是否能拆成n個重複的子串。那麼既然能拆分成多個子串,那麼每個子串的長度肯定不能大於原字串長度的一半,那麼我們可以從原字串長度的一半遍歷到1,如果當前長度能被總長度整除,說明可以分成若干個子字串,我們將這些子字串拼接起來看跟原字串是否相等。 如果拆完了都不相等,返回false。

解法一:

class Solution {
public:
    bool repeatedSubstringPattern(string str) {
        int n = str.size();
        for (int i = n / 2; i >= 1; --i) {
            if (n % i == 0) {
                int c = n / i;
                string t = "";
                for (int j = 0; j < c; ++j) {
                    t 
+= str.substr(0, i); } if (t == str) return true; } } return false; } };

下面這種方法是參考的網上的這個帖子,原作者說是用的KMP演算法,LeetCode之前也有一道應用KMP演算法來解的題Shortest Palindrome,但是感覺那道題才是KMP演算法。這道題也稱為KMP演算法感覺怪怪的(關於KMP的詳細介紹請參見從頭到尾徹底理解KMP,也可以看博主自己寫的一篇KMP Algorithm 字串匹配演算法KMP小結),KMP演算法中的next陣列是找當前位置的最大相同字首字尾的個數,而這道題維護的一位陣列dp[i]表示,到位置i-1為止的重複字串的字元個數,不包括被重複的那個字串,什麼意思呢,我們舉個例子,比如"abcabc"的dp陣列為[0 0 0 0 1 2 3],dp陣列長度要比原字串長度多一個。那麼我們看最後一個位置數字為3,就表示重複的字串的字元數有3個。如果是"abcabcabc",那麼dp陣列為[0 0 0 0 1 2 3 4 5 6],我們發現最後一個數字為6,那麼表示重複的字串為“abcabc”,有6個字元。那麼怎麼通過最後一個數字來知道原字串是否由重複的子字串組成的呢,首先當然是最後一個數字不能為0,而且還要滿足dp[n] % (n - dp[n]) == 0才行,因為n - dp[n]是一個子字串的長度,那麼重複字串的長度和肯定是一個子字串的整數倍,參見程式碼如下:

解法二:

class Solution {
public:
    bool repeatedSubstringPattern(string str) {
        int i = 1, j = 0, n = str.size();
        vector<int> dp(n + 1, 0);
        while (i < n) {
            if (str[i] == str[j]) dp[++i] = ++j;
            else if (j == 0) ++i;
            else j = dp[j];
        }
        return dp[n] && (dp[n] % (n - dp[n]) == 0);
    }
};

類似題目:

參考資料: