459.重复的子字符串

一、直接记结论
将两个 s 连在一起,并移除第一个和最后一个字符。如果 s 是该字符串的子串,那么 s 就满足: 它可以由它的一个子串重复多次构成。

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        string ss = s + s;
        ss.erase ( ss.begin() );
        ss.erase ( ss.end() - 1 );

        if( ss.find(s) == std::string::npos)
            return false;
        else 
            return true;
    }
};

二、利用KMP
如果一个字符串s是由重复子串组成,那么 最长相等前后缀不包含的子串一定是字符串s的最小重复子串。
先确定字符串s 具有最长相等前后缀,然后再看能否整除。

class Solution {
public:
    void getNext( string& s, int* next)
    {
        int j = 0;
        next[0] = 0;

        for(int i = 1; i < s.size(); i++ )
        {
            while( j>0 && s[j] != s[i])
            {
                j = next[j-1];
            }
            
            if(s[j] == s[i])
            {
                j++;
            }
            next[i] = j;
        }
    }

    bool repeatedSubstringPattern(string s) {
        
       vector<int> next( s.size() );
       getNext(s, &next[0]);

        int len = s.size();

		//next[len-1]!=0 说明字符串s具有最长公共前后缀(next[i]的意义)
        if( next[ len-1 ] != 0 && (s.size() % ( len - next[ len-1 ]) == 0) )
            return true;
        else
            return false;
    }
};
posted @ 2025-02-28 21:06  名字好难想zzz  阅读(10)  评论(0)    收藏  举报