Longitud Máxima de Subcadena de Paréntesis Balanceados

Algoritmo 1: Pila

La solución utiliza una pila para rastrear paréntesis no emparejados y sus posiciones. Al encontarr un paréntesis de cierre que coincide con el tope de la pila, se extrae el elemento y se calcula la longitud de la subcadena válida. Si la pila queda vacía tras la extracción, la subcadena abarca desde el inicio; de lo contrario, comienza después de la posición actual del tope.

#include <iostream>
#include <stack>
#include <cstring>
using namespace std;

bool esParCompatible(char abierto, char cerrado) {
    if (abierto == '(' && cerrado == ')') return true;
    if (abierto == '[' && cerrado == ']') return true;
    if (abierto == '{' && cerrado == '}') return true;
    return false;
}

int main() {
    string secuencia;
    cin >> secuencia;
    stack<pair<char, int>> pila;
    int maxLongitud = 0;

    for (int idx = 0; idx < secuencia.size(); idx++) {
        if (!pila.empty() && esParCompatible(pila.top().first, secuencia[idx])) {
            pila.pop();
            if (pila.empty()) {
                maxLongitud = max(maxLongitud, idx + 1);
            } else {
                maxLongitud = max(maxLongitud, idx - pila.top().second);
            }
        } else {
            pila.push({secuencia[idx], idx});
        }
    }
    cout << maxLongitud << endl;
    return 0;
}

Algoritmo 2: Programación Dinámica

Se define dp[i] como la longitud de la subcadena válida más larga que termina en la posición i. Para un paréntesis de cierre en i, se verifica si el carácter en la posición j = i - dp[i-1] - 1 es un paréntesis de apertura coincidente. Si hay coincidencia, se actauliza dp[i] sumando la longitud del par actual (dp[i-1] + 2) y cualquier subcadena válida adyacente anterior (dp[j-1]).

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int TAM_MAX = 100010;
int dp[TAM_MAX];

bool esParValido(char abierto, char cerrado) {
    if (abierto == '(' && cerrado == ')') return true;
    if (abierto == '[' && cerrado == ']') return true;
    if (abierto == '{' && cerrado == '}') return true;
    return false;
}

int main() {
    string entrada;
    cin >> entrada;
    int n = entrada.size();
    int resultado = 0;

    for (int i = 1; i < n; i++) {
        if (entrada[i] == '(' || entrada[i] == '[' || entrada[i] == '{') continue;
        
        int posAnterior = i - dp[i-1] - 1;
        if (posAnterior >= 0 && esParValido(entrada[posAnterior], entrada[i])) {
            dp[i] = dp[i-1] + 2;
            if (posAnterior - 1 >= 0) {
                dp[i] += dp[posAnterior - 1];
            }
            resultado = max(resultado, dp[i]);
        }
    }
    cout << resultado << endl;
    return 0;
}

Etiquetas: pila programacion-dinamica parentesis-balanceados

Publicado el 7-13 23:49