Поскольку мы можем просто игнорировать все буквенно-цифровые символы, мы будем предполагать, что строка теперь содержит только круглые скобки. Как и в вопросе, есть только один вид скобок, "()".
Если мы продолжаем удалять сбалансированные скобки до тех пор, пока не удастся удалить более сбалансированные скобки, все оставшиеся скобки должны выглядеть как «))…) ((… (», которые являются несбалансированными скобками. Это наблюдение предполагает, что мы должны сначала найти эту поворотную точку до которого у нас есть только несбалансированные закрывающие скобки, а после чего у нас только несбалансированные открывающие скобки.
Вот алгоритм. В двух словах, он сначала вычисляет поворотный момент. Затем он выводит дополнительную закрывающую скобку, сканируя строку от начала вправо до точки поворота. Симметрично выводит лишнюю открывающую скобку, сканируя от конца влево до точки поворота.
Позвольте str
быть строкой как массив символов, чей размер равен .n
Инициализировать turning_point=0, maximum_count=0, count=0
. Для каждого i
из них 0
необходимо n-1
сделать следующее.
- Если
str[i] = ')'
добавить 1 к count
; в противном случае вычтите 1.
- Если
count > maximum_count
, установите turning_point=i
и maximum_count=count
.
Теперь turning_point
указатель поворота.
Сброс maximum_count=0, count=0
. Для каждого i
из них 0
необходимо turning_point
сделать следующее.
- Если
str[i] = ')'
добавить 1 к count
; в противном случае вычтите 1.
- Если
count > maximum_count
установить maximum_count = count
. Выведите i
как индекс несбалансированной закрывающей скобки.
Сброс maximum_count=0, count=0
. Для каждого i
из n-1
к turning_point+1
вниз сделайте следующее.
- Если
str[j] = '('
добавить 1 к count
; в противном случае вычтите 1.
- Если
count > maximum_count
установить maximum_count = count
. Выведите i
как индекс несбалансированной открывающей скобки.
Понятно, что алгоритм выполняется за времени и вспомогательной памяти и выходной памяти, где - количество несбалансированных скобок.O(n)O(1)O(u)u
Если мы проанализируем алгоритм выше, мы увидим, что на самом деле нам вообще не нужно находить и использовать поворотный момент. Приятное наблюдение, что все несбалансированные закрывающие скобки происходят до того, как все несбалансированные открывающие скобки можно игнорировать, хотя это и интересно.
Просто нажмите «запустить», чтобы увидеть несколько результатов теста.
Упражнение 1. Покажите, что вышеприведенный алгоритм выведет набор скобок с наименьшим количеством элементов, чтобы оставшиеся скобки были сбалансированы.
Задача 1. Можем ли мы обобщить алгоритм на случай, когда строка содержит два вида скобок, таких как "() []"? Мы должны определить, как распознать и обработать новую ситуацию, случай чередования, "([)]".