LeetCode-1745. Palindrome Partitioning IV-Analysis and Code (Java)

LeetCode-1745. Particionamiento en palíndromo IV [Particionamiento en palíndromo IV] -Análisis y código [Java]

1. Tema

Darle una cadena s, si se puede dividir en tres subcadenas de palíndromo no vacías, devuelva verdadero, de lo contrario devuelva falso.
Cuando una cadena se lee exactamente igual que se lee al revés, se denomina cadena palíndromo.

Ejemplo 1:

输入:s = "abcbdd"
输出:true
解释:"abcbdd" = "a" + "bcb" + "dd",三个子字符串都是回文的。

Ejemplo 2:

输入:s = "bcbddxy"
输出:false
解释:s 没办法被分割成 3 个回文子字符串。

inmediato:

  • 3 <= s. Longitud <= 2000
  • s contiene solo letras minúsculas en inglés.

Fuente: LeetCode (LeetCode)
Enlace: https://leetcode-cn.com/problems/palindrome-partitioning-iv Los
derechos de autor son propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Dos, análisis y código

1. Enumeración en ambos extremos

(1) Pensando

Debido a que el límite entre un extremo de la primera y la tercera subcadenas se fija al principio y al final de la cadena, los valores posibles del otro extremo se pueden encontrar primero y luego enumerar para probar si la segunda cadena en el medio constituye una subcadena palíndromo, hasta que encuentra una solución factible o un recorrido completo.

(2) Código

class Solution {
    
    
    public boolean checkPartitioning(String s) {
    
    
        char[] c = s.toCharArray();
        int len = s.length();
        List<Integer> l1list = new ArrayList<>();
        List<Integer> l2list = new ArrayList<>();
        for (int l1 = 1; l1 < len - 1; l1++) {
    
    
            if (check(c, 0, l1 - 1))
                l1list.add(l1);
        }
        for (int l2 = len - 1; l2 > 1; l2--) {
    
    
            if (check(c, l2, len - 1))
                l2list.add(l2);
        }
        
        for (int i = 0; i < l1list.size(); i++) {
    
    
            for (int j = 0; j < l2list.size(); j++) {
    
    
                if (l1list.get(i) < l2list.get(j) && check(c, l1list.get(i), l2list.get(j) - 1))
                    return true;
            }
        }
        return false;
    }
    
    public boolean check(char[] c, int l, int r) {
    
    
        while (l < r) {
    
    
            if (c[l++] != c[r--])
                return false;
        }
        return true;
    }
}

(3) Resultados

Tiempo de ejecución: 388 ms, superando al 5,05% de los usuarios
en todas las presentaciones de Java ; consumo de memoria: 37,1 MB, superando al 97,01% de los usuarios en todas las presentaciones de Java.

2. Programación dinámica

(1) Pensando

Diseñe una matriz booleana bidimensional dp [i] [j] para registrar si la subcadena con el subíndice [i, j] es una cadena palíndromo. Debido a que las subcadenas palíndromas solo se pueden obtener extendiendo desde el centro de simetría a ambos lados, todas las subcadenas palíndromas se pueden calcular primero y luego atravesar para encontrar si la cuerda original se puede dividir en 3 subcadenas palíndromas.

(2) Código

class Solution {
    
    
    public boolean checkPartitioning(String s) {
    
    
        char[] c = s.toCharArray();
        int len = s.length();
        boolean[][] dp = new boolean[len][len];
        for (int i = 0; i < len; i++)
            for (int j = 0; j < len; j++)
                dp[i][j] = false;
        for (int i = 0; i < len; i++) {
    
    //单个字母及延伸的回文字符串
            int halflen = 0;
            while (i - halflen >= 0 && i + halflen < len && c[i - halflen] == c[i + halflen])
                dp[i - halflen][i + halflen++] = true;
        }
        for (int i = 1; i < len; i++) {
    
    //相同的2个字母及延伸的回文字符串
            if (c[i - 1] == c[i]) {
    
    
                int halflen = 0;
                while (i - 1 - halflen >= 0 && i + halflen < len && c[i - 1 - halflen] == c[i + halflen])
                    dp[i - 1 - halflen][i + halflen++] = true;
            }
        }

        for (int l = 1; l < len - 1; l++) {
    
    //l,r表示分割点,区间左闭右开
            if (dp[0][l - 1])
                for (int r = l + 1; r < len; r++)
                    if (dp[l][r - 1] && dp[r][len - 1])
                        return true;
        }
        return false;
    }
};

(3) Resultados

Tiempo de ejecución: 84 ms, superando al 68,28% de los usuarios
en todas las presentaciones de Java ; consumo de memoria: 42,2 MB, superando al 65,52% de los usuarios en todas las presentaciones de Java.

Tres, otro

Este problema también se puede resolver con el método de Manacher en complejidad de tiempo lineal.

Supongo que te gusta

Origin blog.csdn.net/zml66666/article/details/113817726
Recomendado
Clasificación