Есть строка, состоящая из разных скобок, необходимо проверить, закрыты ли все
Дана строка, состоящая из скобок, например: ([{}]). Скобки могут быть круглые: (), квадратные: [], фигурные: {}.
Необходимо проверить закрытость всех скобок в строке.
Примеры:
isValidBraces("()") === true
isValidBraces("[)") === false
isValidBraces("{}[]()") === true
isValidBraces("([{}])") === true
isValidBraces("())({}}{()][][") === false
Теория и алгоритм
Стек подходит для этой задачи, потому что корректная вложенность означает: последняя открытая скобка должна закрыться первой, то есть требуется поведение LIFO. Алгоритм поддерживает инвариант: в стеке лежат только те открывающие скобки, которые ещё не закрыты, а верхушка — та, которую нужно закрыть следующей.
Таблица соответствий (ожидаемая «пара»):
(↔)[↔]{↔}
Пошаговый алгоритм:
- Создать пустой стек.
- Читать строку слева направо.
- Если символ — открывающая скобка, положить её в стек.
- Если символ — закрывающая скобка, то:
- Если стек пуст, строка некорректна (закрывать нечего).
- Иначе взять верхний элемент стека и проверить, что тип совпадает (например,
)закрывает только(). - Если тип совпал — удалить верхний элемент, иначе строка некорректна.
- После чтения всей строки строка корректна только если стек пуст (не осталось незакрытых скобок).
Схема работы на примере ([{}]):
Строка: ( [ { } ] )
Стек: ( // встретилась '(' -> push
( [ // встретилась '[' -> push
( [ { // встретилась '{' -> push
( [ // встретилась '}' -> pop '{'
( // встретилась ']' -> pop '['
пусто // встретилась ')' -> pop '('
Итог: стек пуст -> true
"([)]" имеет одинаковое количество скобок, но является некорректной из-за неправильного порядка закрытия.Разбор примеров и ошибок
Ошибки возникают в двух базовых ситуациях: закрывающая скобка встречается при пустом стеке или закрывающая скобка не соответствует верхушке стека (неправильный тип). Важно проверять обе ситуации сразу при обработке закрывающей скобки, чтобы завершать работу ранним возвратом false.
Разбор примеров из условия:
"()"→(кладётся в стек, затем)снимает(, стек пуст, результатtrue."[)"→[кладётся в стек, затем)пытается закрыть(, но на верхушке[, результатfalse."{}[]()"→ три независимые пары, стек каждый раз становится пустым, результатtrue."([{}])"→ строго вложенные пары, верхушка каждый раз совпадает с нужным типом, результатtrue."())({}}{()][]["→ в процессе обязательно появится либо преждевременное закрытие (стек пуст), либо несовпадение типов, либо останутся незакрытые скобки в конце, результатfalse.
Таблица «симптом → причина → что делать»:
| Симптом | Причина | Проверка в коде |
|---|---|---|
Встречена )/]/} при пустом стеке | Закрывающая без пары слева | if (stack.length === 0) return false; |
Типы не совпали (например, в стеке [, а пришло )) | Нарушена вложенность | if (top !== needOpen) return false; |
| После прохода стек не пуст | Остались незакрытые открывающие | return stack.length === 0; |
Кратко: проверка корректности скобок делается стеком — открывающие помещаются в стек, закрывающие сравниваются с верхушкой и удаляют её при совпадении; ошибка возникает при пустом стеке на закрытии, несовпадении типов или непустом стеке после прохода всей строки.