(85) 214. La cuerda palíndromo más corta (código leet)

题目链接:
https://leetcode-cn.com/problems/shortest-palindrome/
难度:困难
214. 最短回文串
	给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。
找到并返回可以用这种方式转换的最短回文串。
示例 1:
	输入: "aacecaaa"
	输出: "aaacecaaa"
示例 2:
	输入: "abcd"
	输出: "dcbabcd"

Esta pregunta no se sentirá más que rentable

Idea: Primero, hablemos del método (no pensé en una buena manera, pero la más simple violencia sin cerebro): la
cadena add + s es una cadena palíndromo, y add <| s | (s elimina el primer carácter y voltea es add Caso máximo) Supongamos que s tiene una cadena de prefijo s1 con longitud | s | - | agregar |, un sufijo s2 con longitud | agregar |, y el cambio de prefijo s1 para la cadena palíndromo s2 es agregar,
es decir, encontramos el mejor de s El prefijo largo s1, volteando la cadena restante se agrega


Mi comprensión de Rabin-Karp es convertir la cadena en un número de acuerdo a ciertas reglas de asignación.
En circunstancias ideales, no hay conflicto (en esta pregunta, lo que reduce la probabilidad de conflictos no significa que no hay conflicto !!!)
cálculo Si el prefijo de la cadena s tiene el mismo valor hash que el valor hash invertido, entonces es una cadena palíndromo.
Para el valor hash directo de s1: hash (si) = hash (s (i-1)) * base + si
Para el valor hash inverso de s1: hash (-si) = hash (-s (i-1)) + si * base i (puede usar un número para registrar aquí)

class Solution {
    
    
public:
    string shortestPalindrome(string s) {
    
    
        int n=s.size();
        int base = 131, mod = 1000000007;
        // record 记录base的i次方的值
        int left = 0, right = 0, record = 1;
        int best = -1;
        for(int i=0;i<n;++i){
    
    
            left=((long long)left*base+s[i])%mod;
            right=(right+s[i]*(long long)record)%mod;
            if(left==right){
    
    
                best=i;
            }
            record=((long long)record*base)%mod;
        }
        string add = (best == n - 1 ? "" : s.substr(best + 1, n));
        reverse(add.begin(), add.end());
        return add + s;
    }
};

KMP. . . . Hace unos días, escribí el código escrito el día 24 para usarlo. Todavía no entiendo que
s1 es un palíndromo. Busque s1 en el orden inverso de s (probablemente ...)

class Solution {
    
    
public:
    string shortestPalindrome(string s) {
    
    
        int n = s.size();
        vector<int> nextTable(n, -1);
        // 求出nesxtTable数组
        for (int i = 1; i < n; ++i) {
    
    
            int j = nextTable[i - 1];
            while (j != -1 && s[j + 1] != s[i]) {
    
    
                j = nextTable[j];
            }
            if (s[j + 1] == s[i]) {
    
    
                nextTable[i] = j + 1;
            }
        }
        int match=-1;
        for(int i=n-1;i>=0;--i){
    
    
            while (match != -1 && s[match + 1] != s[i]) {
    
    
                match = nextTable[match];
            }
            if (s[match + 1] == s[i]) {
    
    
                ++match;
            }
        }
        string add = (match == n - 1 ? "" : s.substr(match + 1, n));
        reverse(add.begin(), add.end());
        return add+s;
    }
};

Supongo que te gusta

Origin blog.csdn.net/li_qw_er/article/details/108289682
Recomendado
Clasificación