Поскольку мы можем просто игнорировать все буквенно-цифровые символы, мы будем предполагать, что строка теперь содержит только круглые скобки. Как и в вопросе, есть только один вид скобок, "()".
Если мы продолжаем удалять сбалансированные скобки до тех пор, пока не удастся удалить более сбалансированные скобки, все оставшиеся скобки должны выглядеть как «))…) ((… (», которые являются несбалансированными скобками. Это наблюдение предполагает, что мы должны сначала найти эту поворотную точку до которого у нас есть только несбалансированные закрывающие скобки, а после чего у нас только несбалансированные открывающие скобки.
Вот алгоритм. В двух словах, он сначала вычисляет поворотный момент. Затем он выводит дополнительную закрывающую скобку, сканируя строку от начала вправо до точки поворота. Симметрично выводит лишнюю открывающую скобку, сканируя от конца влево до точки поворота.
Позвольте 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. Можем ли мы обобщить алгоритм на случай, когда строка содержит два вида скобок, таких как "() []"? Мы должны определить, как распознать и обработать новую ситуацию, случай чередования, "([)]".