1. 程式人生 > >C#LeetCode刷題之#459-重複的子字串(Repeated Substring Pattern)

C#LeetCode刷題之#459-重複的子字串(Repeated Substring Pattern)

問題

給定一個非空的字串,判斷它是否可以由它的一個子串重複多次構成。給定的字串只含有小寫英文字母,並且長度不超過10000。

輸入: "abab"

輸出: True

解釋: 可由子字串 "ab" 重複兩次構成。

輸入: "aba"

輸出: False

輸入: "abcabcabcabc"

輸出: True

解釋: 可由子字串 "abc" 重複四次構成。 (或者子字串 "abcabc" 重複兩次構成。)


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.

Input: "abab"

Output: True

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

Input: "aba"

Output: False

Input: "abcabcabcabc"

Output: True

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


示例

public class Program {

    public static void Main(string[] args) {
        var s = "Iori's Blog";

        var res = RepeatedSubstringPattern(s);
        Console.WriteLine(res);

        s = "abaababaab";

        res = RepeatedSubstringPattern2(s);
        Console.WriteLine(res);

        Console.ReadKey();
    }

    private static bool RepeatedSubstringPattern(string s) {
        //LeetCode 超出記憶體限制,未AC
        //基本思路是一個指標截斷字串
        //指標前所有的字串為子字串參考計算
        //往後迴圈看每一段是否相同
        //如果每一段都相同,則滿足題意
        for(var i = 0; i < s.Length / 2; i++) {
            var sub = s.Substring(0, i + 1);
            if(s.Length % sub.Length != 0) continue;
            var nums = s.Length / sub.Length;
            for(var j = 1; j < nums; j++) {
                if(s.Substring(j * sub.Length, sub.Length) != sub) break;
                if(j == nums - 1) return true;
            }
        }
        return false;
    }

    private static bool RepeatedSubstringPattern2(string s) {
        //基本思路是一個指標截斷字串
        //指標前所有的字串為子字串參考計算
        //以此字串迴圈構建新字元
        //比較新構建的字串是否和原串相同
        //變數 repeat 不能使用字串,否則效率較低
        //LeetCode 會TLE超時無法AC
        var length = s.Length;
        for(var i = length / 2; i >= 1; i--) {
            if(length % i == 0) {
                var repeat = new StringBuilder();
                for(var j = 0; j < length / i; j++) {
                    repeat.Append(s.Substring(0, i));
                }
                if(repeat.ToString() == s) return true;
            }
        }
        return false;
    }

}

以上給出2種演算法實現,以下是這個案例的輸出結果:

False
True

分析:

顯而易見,以上2種演算法的時間複雜度均為: O(n^{2}) 。