[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);
    }
};

 

類似題目:

Implement strStr()

Repeated String Match

 

參考資料:

https://discuss.leetcode.com/topic/68498/one-line-with-regex/2

https://discuss.leetcode.com/topic/67992/java-simple-solution-with-explanation

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM