Longest Common Subsequence (LCS) encuentra la subsecuencia más larga que aparece en el mismo orden relativo en dos secuencias. A diferencia de substring, los caracteres no necesitan ser contiguos — solo preservar el orden.
Es uno de los problemas DP más icónicos, con aplicaciones en diff de texto, bioinformática (alineamiento de ADN), y como base para edit distance.
Cómo Funciona
- Inicializa tabla DP
dp[i][j]= longitud LCS deA[0..i)yB[0..j). - Recurre:
- “Si
A[i-1] == B[j-1]:dp[i][j] = 1 + dp[i-1][j-1](match)” - “Si no:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])(skip)”
- “Si
- Resultado:
dp[m][n] - Reconstruye: backtrack desde
dp[m][n]para obtener la secuencia actual.
Idea Clave
LCS es un ejercicio de match o skip: en cada posición (i,j), o los caracteres coinciden y los usas, o no coinciden y debes saltar uno de ellos. La tabla 2D captura todas las combinaciones de prefijos.
La reconstrucción requiere backtrack: desde dp[m][n], si A[i-1] == B[j-1] ese carácter está en el LCS; si no, sigue la dirección del máximo.
Ejemplo Trabajado
A = "ABCBDAB", B = "BDCABA"
Tabla DP (longitudes):
Ø B D C A B A
Ø [ 0, 0, 0, 0, 0, 0, 0 ]
A [ 0, 0, 0, 0, 1, 1, 1 ]
B [ 0, 1, 1, 1, 1, 2, 2 ]
C [ 0, 1, 1, 2, 2, 2, 2 ]
B [ 0, 1, 1, 2, 2, 3, 3 ]
D [ 0, 1, 2, 2, 2, 3, 3 ]
A [ 0, 1, 2, 2, 3, 3, 4 ]
B [ 0, 1, 2, 2, 3, 4, 4 ]
Resultado: dp[7][6] = 4. LCS = "BCBA" o "BDAB" (empate).
Casos Extremos y Trampas
- Sin caracteres comunes — LCS = 0.
- Secuencias idénticas — LCS = longitud completa.
- Espacio — se puede reducir a
O(min(m,n))si solo necesitas la longitud, no la secuencia. - Reconstrucción — requiere la tabla completa o clever on-the-fly.
Comparación con Variantes
| Problema | Match | Complejidad | Uso |
|---|---|---|---|
| LCS | No contiguo | O(mn) | Diff, bioinformática |
| LCSubstr | Contiguo | O(mn) | Plagio detección |
| Edit Distance | Ins/del/replace | O(mn) | diff, spell check |
Aplicaciones
- Diff de texto — git diff, Word track changes
- Bioinformática — alineamiento de ADN/ARN (Needleman-Wunsch)
- Sistemas de control de versiones — merge de cambios
- Enseñanza — ejemplo clásico de DP 2D con backtracking
Trayectoria de Práctica
- Implementa LCS con tabla 2D; traza
A="ABCBDAB",B="BDCABA". - Añade backtracking para reconstruir la secuencia actual.
- Modifica para retornar la longitud solo, usando
O(min(m,n))espacio. - Compara con longest common substring: ¿por qué la recurrencia cambia?
- Extiende a edit distance (Levenshtein): añade operación de replace.