459. Subcadena repetida (KMP)

 

Dada una cadena no vacía, juzgue si puede estar compuesta por una subcadena repetida varias veces. La cadena dada contiene solo letras minúsculas en inglés y la longitud no excede las 10,000.

Ejemplo 1:

Entrada: "abab"

Salida: Verdadero

Explicación: La subcadena "ab" se puede repetir dos veces.
Ejemplo 2:

Entrada: "aba"

Resultado: Falso
Ejemplo 3:

Entrada: "abcabcabcabc"

Salida: Verdadero

Explicación: La subcadena "abc" se puede repetir cuatro veces. (O la subcadena "abcabc" se repite dos veces).

Análisis: Utilice principalmente este tema para dominar el método de construcción de la siguiente matriz, primero establezca el valor de next [0] (este valor también determina la representación general de la siguiente matriz), inicialice la posición de i, j y atraviese el cadena con la posición de i, cada recorrido compara la relación de igualdad entre s [i] y s [j] (no quiero esperar a que la posición de j retroceda. Un retroceso significa que el valor del mismo prefijo y el sufijo en la posición de i también se reduce. De manera similar, si es igual, se agrega j. 1) Al final de cada ciclo, cuántos caracteres consecutivos iguales (cadenas) se representan de acuerdo con la posición actual de j, es decir , siguiente [i] = j. Con la siguiente matriz, es equivalente a un almacenamiento de memoria. Encuentra la palabra en el bucle for doble Puedes omitir el recorrido en el bucle exterior de la cadena para reducir el recorrido inútil. El código es el siguiente :

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

Supongo que te gusta

Origin blog.csdn.net/qq_34612223/article/details/113870696
Recomendado
Clasificación