Решение ниже имеет сложность времени O (n) и сложность пространства O (1).
Это очень интуитивно понятно.
Сначала мы пересекаем строку слева направо, ищем самую длинную допустимую подстроку парен, используя метод count, который обычно используется для проверки правильности параметров parens. При этом мы также записываем максимальную длину такой подстроки, если она найдена.
Затем мы делаем то же самое, идя справа налево.
Алгоритм будет выглядеть следующим образом:
// Initialize variables
1. count = 0, len = 0, max_len_so_far = 0
// Check for longest valid string of parens while traversing from left to right
2. iterate over input string from left to right:
- len += 1
- if next character is '(',
count += 1
- if next character is ')',
count -= 1
- if (count == 0 and len > max_len_so_far),
max_len_so_far = len
- if (count < 0),
len = 0, count = 0
// Set count and len to zero again, but leave max_len_so_far untouched
3. count = 0, len = 0
// Now do a very similar thing while traversing from right to left
// (Though do observe the switched '(' and ')' in the code below)
4. iterate over input string from right to left:
- len += 1
- if next character is ')',
count += 1
- if next character is '(',
count -= 1
- if (count == 0 and len > max_len_so_far),
max_len_so_far = len
- if (count < 0),
len = 0, count = 0
// max_len_so_far is now our required answer
5. Finally,
return max_len_so_far
В качестве примера рассмотрим строковое
"((())"
Пусть эта строка нулевой индексируются.
Сначала мы идем влево.
Таким образом, при индексе 0 счет будет равен 1, затем 2 по индексу 1, 3 по индексу 2, 2 по индексу 3 и 1 по индексу 4. На этом этапе max_len даже не изменится, поскольку счет снова не 0.
Затем мы идем направо налево.
При индексе 4 счетчик равен 1, затем 2 по индексу 3, затем 1 по индексу 2, затем 0 по индексу 1.
В этот момент len равно 4 и max_len_so_far = 0, поэтому мы устанавливаем max_len = 4.
Затем, при индексе 0, счет равен 1.
На этом этапе мы останавливаем и возвращаем 4, что действительно является правильным ответом.
Доказательство правильности остается в качестве инклюзивного упражнения для читателя.
ПРИМЕЧАНИЕ. Этот алгоритм также может быть очень просто изменен, чтобы вернуть самую длинную допустимую подстроку скобок, а не только ее длину.
Слышали ли вы о подсчете скобок? Когда вы добавляете 1 к счетчику для каждого '(' и вычитаете 1 для каждого ')'? –