发布于 2026-01-06 1 阅读
0

Валидация скобочной последовательности

Валидация скобочной последовательности

Давайте разберем популярную задачу валидации скобочной последовательности。
Ее можно найти вот здесь有效括号

普罗斯塔诺夫卡·扎达奇

Дана некоторая строка, содержащая символы '(', ')', '{', '}', '[' и ']'。 Необходимо определить,является ли данная строка валидной скобочной последовательностью。

Скобочная последовательность является валидной при выполнении двух условий:

  1. Открывающие скобки закрываются скобками того же типа
  2. Открывающие скобки закрываются в правильном порядке

Примеры входных данных

示例 1

() - данная строка является правильной скобочной последовательностью, так как выполняются условия 1 和 2

示例 2

()[]{} - данная строка является правильной скобочной последовательностью, так как выполняются условия 1 和 2

示例 3

([]) - данная строка является правильной скобочной последовательностью, так как выполняются условия 1 和 2

示例 4

([]} - данная строка не является правильной скобочной последовательностью, так как не выполняетс первое условие

示例 5

({)} - данная строка не является правильной скобочной последовательностью, так как не выполняетс второе условие

Решение

Первой идеей может быть сделать подсчет количества открывающих 和 закрывающих скобок。 Но тогда мы можем не удовлетворить второму условию。 Поэтому порядок нам тоже важен。 Для этого нам надо выбрать структуру стек。 Мы будем складывать в него открывающие скобки, а при встрече закрывающих - доставать их.

Для стека нам подойдет класс ArrayDeque,это реализация двухсторонней очереди。

Решение по шагам

1) Достаем очередной элемент из строки。 Для этого итерируемся по строке с помощью конструкции forEach。 Каждый элемент в итерации будет иметь тип Char.

s.forEach { char ->
    ...
}
Enter fullscreen mode Exit fullscreen mode

2) Проверяем, является ли он открывающей или закрывающей скобкой. Для этого мы используем конструкцию 当
3) Если скобка открывающая, то кладем в стек

...
when(char) {
    '(' -> stack.addLast(char)
    '[' -> stack.addLast(char)
    '{' -> stack.addLast(char)
    ...
}
...
Enter fullscreen mode Exit fullscreen mode

4) Если скобка закрывающая, то достаем скобку из стека и сравниваем на соответствие
5) Если скобки соответствуют, то итерируемся дальше
6) Если скобки не соответствуют, то возвращаем false

when(char) {
    ...
    else -> if (stack.isNotEmpty() || isCorrectChar(stack.removeLast())) return false
}
...
Enter fullscreen mode Exit fullscreen mode

7) В конце возвращаем true, если стек пустой, и false, если в стеке остались элементы

return stack.isEmpty()
Enter fullscreen mode Exit fullscreen mode

Оптимизация

Поскольку мы кладем в стек открывающую скобку, возникает необходимость сравнения на соответствие с закрывающей。广告 广告 广告 广告 广告 广告 广告 广告 广告Вместо этого можно сразу класть в стек соответствующую закрывающую скобку,а затем сравнивать на равенство。

when(char) {
    '(' -> stack.add(')')
    '[' -> stack.add(']')
    '{' -> stack.add('}')
}
Enter fullscreen mode Exit fullscreen mode

Оценка сложности

  • По времени - O(s.length)。 Мы циклом проходимся по всей строке, что дает нам O(s.length)。 Так же мы используем операции вставки и извлечения в конец двухсторонней очереди, что дает O(1)。

  • По памяти - O(s.length)。 Максимальный размер дополнительно используемой памяти - O(s.length), так как в стэк мы не добавляем больше длины входных данных。

Полное решение

fun isValid(s: String): Boolean {
    val stack = ArrayDeque<Char>()
    s.forEach { char ->
        when(char) {
            '(' -> stack.addLast(')')
            '[' -> stack.addLast(']')
            '{' -> stack.addLast('}')
            else -> if (stack.isNotEmpty() || stack.removeLast() != char) return false
        }
    }
    return stack.isEmpty()
}
Enter fullscreen mode Exit fullscreen mode
文章来源:https://dev.to/ivsivak/validatsiia-skobochnoi-posliedovatielnosti-ai1