Poiché possiamo semplicemente ignorare tutti i caratteri alfanumerici, supponiamo che la stringa contenga solo parentesi da ora in poi. Come nella domanda, esiste solo un tipo di parentesi, "()".
Se continuiamo a rimuovere le parentesi bilanciate fino a quando non è possibile rimuovere più parentesi bilanciate, tutte le parentesi rimanenti devono apparire come ")) ...) ((... (", che sono tutte parentesi sbilanciate. Questa osservazione suggerisce che dovremmo trovare prima quel punto di svolta , prima del quale abbiamo solo parentesi di chiusura sbilanciate e dopo di che abbiamo solo parentesi di apertura sbilanciate.
Ecco l'algoritmo. In breve, calcola prima la svolta. Quindi emette parentesi extra di chiusura, scansionando la stringa dall'inizio a destra fino alla svolta. Simmetricamente, genera parentesi di apertura extra, scansionando dall'estremità a sinistra fino alla svolta.
Lascia che str
sia la stringa come una matrice di caratteri, la cui dimensione è .n
Inizializza turning_point=0, maximum_count=0, count=0
. Per ciascuna i
da 0
a n-1
fare quanto segue.
- Se
str[i] = ')'
, aggiungi 1 a count
; altrimenti, sottrai 1.
- Se
count > maximum_count
, impostare turning_point=i
e maximum_count=count
.
Ora turning_point
è l'indice della svolta.
Ripristina maximum_count=0, count=0
. Per ciascuna i
da 0
a turning_point
fare quanto segue.
- Se
str[i] = ')'
, aggiungi 1 a count
; altrimenti, sottrai 1.
- Se
count > maximum_count
impostato maximum_count = count
. Output i
come indice di una parentesi di chiusura sbilanciata.
Ripristina maximum_count=0, count=0
. Per ciascuno i
da n-1
a turning_point+1
verso il basso, procedi come segue.
- Se
str[j] = '('
, aggiungi 1 a count
; altrimenti, sottrai 1.
- Se
count > maximum_count
impostato maximum_count = count
. Output i
come indice di una parentesi di apertura non bilanciata.
È chiaro che l'algoritmo funziona in tempo e memoria ausiliaria e memoria di output, dove è il numero di parentesi sbilanciate.O(n)O(1)O(u)u
Se analizziamo l'algoritmo sopra, vedremo che, in realtà, non abbiamo bisogno di trovare e usare affatto il punto di svolta. La bella osservazione che tutte le parentesi di chiusura sbilanciate si verificano prima di tutte le parentesi di apertura sbilanciate può essere ignorata sebbene interessante.
Basta premere "Esegui" per vedere diversi risultati del test.
Esercizio 1. Mostra che l'algoritmo sopra riportato produrrà una serie di parentesi con la cardinalità minima in modo tale che le parentesi rimanenti siano bilanciate.
Problema 1. Possiamo generalizzare l'algoritmo al caso quando la stringa contiene due tipi di parentesi come "() []"? Dobbiamo determinare come riconoscere e trattare la nuova situazione, il caso interleaving, "([)]".