Categorías
Algorithms

Leetcode: subcadena palindrómica más larga (Java)

Encontrar la subcadena palindrómica más larga es un problema clásico de codificación de entrevistas. Esta publicación resume 3 soluciones diferentes para este problema.

1. Programación dinámica

Sea s la cadena de entrada, i y j son dos índices de la cadena. Defina una «tabla» de matriz de 2 dimensiones y deje que la tabla[i][j] denotar si una subcadena de i a j es palíndromo.

Condición cambiante:

table[i+1][j-1] == 1 && s.charAt(i) == s.charAt(j)
=>
table[i][j] == 1

Tiempo O (n ^ 2) Espacio O (n ^ 2)

public String longestPalindrome(String s) {
    if(s==null || s.length()<=1)
        return s;
 
    int len = s.length();
    int maxLen = 1;
    boolean [][] dp = new boolean[len][len];
 
    String longest = null;
    for(int l=0; l<s.length(); l++){
        for(int i=0; i<len-l; i++){
            int j = i+l;
            if(s.charAt(i)==s.charAt(j) && (j-i<=2||dp[i+1][j-1])){
                dp[i][j]=true;
 
                if(j-i+1>maxLen){
                   maxLen = j-i+1; 
                   longest = s.substring(i, j+1);
                }
            }
        }
    }
 
    return longest;
}

Por ejemplo, si la cadena de entrada es «dabcba», la matriz final sería la siguiente:

1 0 0 0 0 0 
0 1 0 0 0 1 
0 0 1 0 1 0 
0 0 0 1 0 0 
0 0 0 0 1 0 
0 0 0 0 0 1 

En la tabla, podemos ver claramente que la cadena más larga está en la tabla de celdas.[1][5].

2. Un algoritmo simple

Podemos escanear a ambos lados para cada carácter. Tiempo O (n ^ 2), Espacio O (1)

  Subsecuencia común más larga (Java)
public String longestPalindrome(String s) {
	if (s.isEmpty()) {
		return null;
	}
 
	if (s.length() == 1) {
		return s;
	}
 
	String longest = s.substring(0, 1);
	for (int i = 0; i < s.length(); i++) {
		// get longest palindrome with center of i
		String tmp = helper(s, i, i);
		if (tmp.length() > longest.length()) {
			longest = tmp;
		}
 
		// get longest palindrome with center of i, i+1
		tmp = helper(s, i, i + 1);
		if (tmp.length() > longest.length()) {
			longest = tmp;
		}
	}
 
	return longest;
}
 
// Given a center, either one letter or two letter, 
// Find longest palindrome
public String helper(String s, int begin, int end) {
	while (begin >= 0 && end <= s.length() - 1 && s.charAt(begin) == s.charAt(end)) {
		begin--;
		end++;
	}
	return s.substring(begin + 1, end);
}

3. Algoritmo de Manacher

El algoritmo de Manacher es mucho más complicado de descifrar, aunque traerá el beneficio de la complejidad temporal de O (n). Dado que no es típico, no hay necesidad de perder tiempo en eso.

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *