[LeetCode] Repeated String Match 重復字符串匹配


 

Given two strings A and B, find the minimum number of times A has to be repeated such that B is a substring of it. If no such solution, return -1.

For example, with A = "abcd" and B = "cdabcdab".

Return 3, because by repeating A three times (“abcdabcdabcd”), B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd").

Note:
The length of A and B will be between 1 and 10000.

 

這道題讓我們用字符串B來匹配字符串A,問字符串A需要重復幾次,如果無法匹配,則返回-1。那么B要能成為A的字符串,那么A的長度肯定要大於等於B,所以當A的長度小於B的時候,我們可以先進行重復A,直到A的長度大於等於B,並且累計次數cnt。那么此時我們用find來找,看B是否存在A中,如果存在直接返回cnt。如果不存在,我們再加上一個A,再來找,這樣可以處理這種情況A="abc", B="cab",如果此時還找不到,說明無法匹配,返回-1,參見代碼如下:

 

解法一:

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        int n1 = A.size(), n2 = B.size(), cnt = 1;
        string t = A;
        while (t.size() < n2) {
            t += A;
            ++cnt;
        }
        if (t.find(B) != string::npos) return cnt;
        t += A;
        return (t.find(B) != string::npos) ? cnt + 1 : -1;
    }
};

 

下面這種解法就更簡潔了,思路和上面的一樣,都是每次給t增加一個字符串A,我們其實可以直接算出最多需要增加的個數,即B的長度除以A的長度再加上2,當B小於A的時候,那么可能需要兩個A,所以i就是小於等於2,這樣我們每次在t中找B,如果找到了,就返回i,沒找到,就增加一個A,循環推出后返回-1即可,參見代碼如下:

 

解法二:

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        string t = A;
        for (int i = 1; i <= B.size() / A.size() + 2; ++i) {
            if (t.find(B) != string::npos) return i;
            t += A;
        }
        return -1;
    }
};

 

下面這種解法還是由熱心網友edyyy提供,沒有用到字符串自帶的find函數,而是逐個字符進行比較,循環字符串A中的所有字符,然后用個變量j,初始化為0,用來循環字符串B中的字符,每個字符和A中對應的字符進行比較,此時從A中取字符就要把A當作一個循環數組來處理,用(i+j)%m來取字符,還要確保j小於n,避免越界,如果字符匹配的話,j自增1。while 循環結束后,如果j等於n了,說明B中所有的字符都成功匹配了,那么我們來計算A的重復次數,通過(i+j-1)/m + 1來得到,注意i+j要減1再除以m,之后再加上一次。因為當i+j正好等於m時,說明此時不用重復A,那么(i+j-1)/m + 1還是等於1,當i+j>m的時候,需要重復A了,(i+j-1)/m + 1也可以得到正確的結構,參見代碼如下:

 

解法三:

class Solution {
public:
    int repeatedStringMatch(string A, string B) {
        int m = A.size(), n = B.size();
        for (int i = 0; i < m; ++i) {
            int j = 0;
            while (j < n && A[(i + j) % m] == B[j]) ++j;
            if (j == n) return (i + j - 1) / m + 1;
        }
        return -1;
    }
};

 

類似題目:

Repeated Substring Pattern

 

參考資料:

https://discuss.leetcode.com/topic/105579/c-4-lines-o-m-n-o-1-and-8-lines-kmp-o-m-n-o-n

https://discuss.leetcode.com/topic/105566/java-solution-just-keep-building-oj-missing-test-cases

 

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


免責聲明!

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



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