459. Repeated substring (KMP)

 

Given a non-empty string, judge whether it can be composed of a substring repeated multiple times. The given string contains only lowercase English letters, and the length does not exceed 10,000.

Example 1:

Input: "abab"

Output: True

Explanation: The substring "ab" can be repeated twice.
Example 2:

Input: "aba"

Output: False
Example 3:

Input: "abcabcabcabc"

Output: True

Explanation: The substring "abc" can be repeated four times. (Or the substring "abcabc" is repeated twice.)

Analysis: Mainly use this topic to master the construction method of the next array, first set the value of next[0] (this value also determines the overall representation of the next array), initialize the position of i, j, and traverse the string with the position of i, Each traversal compares the equality relationship between s[i] and s[j] (I don’t want to wait for the position of j to retreat. One retreat means that the value of the same prefix and suffix at the position of i is also reduced. Similarly, if it is equal, j is added. 1) At the end of each loop, how many equal consecutive characters (strings) are represented according to the current position of j, that is, next[i] = j. With the next array, it is equivalent to a memory storage. Find the word in the double for loop You can skip traversal in the outer loop of the string to reduce useless traversal. The code is as follows:

class Solution {
public:
    void getNext(int* next, const string& s){
        next[0] = -1;
        int j = -1;
        for (int i = 1; i < s.size(); i++){
            // 准备j回退的
            while(j >= 0 && s[i] != s[j+1]){
                j = next[j];
            }
            // 向右前进
            if(s[i] == s[j + 1]){
                j++;
            }
            next[i] = j;
        }
        // for (int i = 0; i < s.size(); i++) cout << next[i] << " ";   
             
    }
    bool repeatedSubstringPattern(string s) {
        if (s.size() == 0) return false;
        int next[s.size()];
        getNext(next, s);
        int len = s.size();
        // next[len - 1] + 1 = 3 + 1 = 4,最长公共前后缀的长度
        // 以ababab为例,4就是abab这个公共部分
        if (next[len - 1] != -1 && len % (len - (next[len - 1] + 1)) == 0) {
            return true;
        }
        return false;       
    }
};

Guess you like

Origin blog.csdn.net/qq_34612223/article/details/113870696