Como podemos ignorar todos los caracteres alfanuméricos, asumiremos que la cadena contiene solo paréntesis de ahora en adelante. Como en la pregunta, solo hay un tipo de paréntesis, "()".
Si seguimos eliminando paréntesis equilibrados hasta que no se puedan eliminar más paréntesis equilibrados, todos los paréntesis restantes deben verse como ")) ...) ((... (", que son paréntesis desequilibrados. Esta observación sugiere que deberíamos encontrar primero ese punto de inflexión) , antes de lo cual solo tenemos paréntesis de cierre desequilibrados y después de lo cual solo tenemos paréntesis de apertura desequilibrados.
Aquí está el algoritmo. En pocas palabras, calcula primero el punto de inflexión. Luego genera un paréntesis de cierre adicional, escaneando la cadena desde el inicio hacia la derecha hasta el punto de inflexión. Simétricamente, genera paréntesis de apertura adicionales, escaneando desde el extremo hacia la izquierda hasta el punto de inflexión.
str
n
Initialize turning_point=0, maximum_count=0, count=0
. Para cada uno i
de 0
a n-1
hacer lo siguiente.
- Si
str[i] = ')'
, agregue 1 a count
; de lo contrario, reste 1.
- Si
count > maximum_count
, establecer turning_point=i
y maximum_count=count
.
Ahora turning_point
es el índice del punto de inflexión.
Restablecer maximum_count=0, count=0
. Para cada uno i
de 0
a turning_point
hacer lo siguiente.
- Si
str[i] = ')'
, agregue 1 a count
; de lo contrario, reste 1.
- Si
count > maximum_count
, listo maximum_count = count
. Salida i
como el índice de un paréntesis de cierre desequilibrado.
Restablecer maximum_count=0, count=0
. Para cada uno i
de n-1
hacia turning_point+1
abajo, haga lo siguiente.
- Si
str[j] = '('
, agregue 1 a count
; de lo contrario, reste 1.
- Si
count > maximum_count
, listo maximum_count = count
. Salida i
como el índice de un paréntesis de apertura desequilibrado.
O(n)O(1)O(u)u
Si analizamos el algoritmo anterior, veremos que, de hecho, no necesitamos encontrar y usar el punto de inflexión en absoluto. La agradable observación de que todos los paréntesis de cierre desequilibrados ocurren antes de que todos los paréntesis de apertura desequilibrados puedan ignorarse aunque sean interesantes.
Simplemente presione "ejecutar" para ver varios resultados de la prueba.
Ejercicio 1. Demuestre que el algoritmo anterior generará un conjunto de paréntesis con la menor cardinalidad, de modo que los paréntesis restantes estén equilibrados.
Problema 1. ¿Podemos generalizar el algoritmo al caso cuando la cadena contiene dos tipos de paréntesis como "() []"? Tenemos que determinar cómo reconocer y tratar la nueva situación, el caso de intercalación, "([)]".