Skip to content

Commit

Permalink
Issue##303: Balanced Parentheses
Browse files Browse the repository at this point in the history
  • Loading branch information
aarexer committed Dec 22, 2024
1 parent da2105c commit 6b45e80
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
120 changes: 120 additions & 0 deletions interview/algorithms/easy/balanced_braces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Сбалансированность скобок

Задача с [LeetCode](https://leetcode.com/problems/valid-parentheses/description/).

## Условие

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

Входная строка сбалансирована по скобкам, если:

* Открытые скобки должны быть закрыты скобками того же типа.

* Открытые скобки должны быть закрыты в правильном порядке.

* Каждой закрывающейся скобке соответствует открытая скобка того же типа.

### Примеры

```text
Input: s = "()"
Output: true
Input: s = "()[]{}"
Output: true
Input: s = "(]"
Output: false
Input: s = "([])"
Output: true
```

## Решение

### Очередь

Основное правило согласованности состоит в том, что открытые скобки должны быть закрыты в правильном порядке скобками того же типа.
Для обеспечения порядка нам нужна `LIFO` структура данных, в `Java` для этого можно использовать `java.util.ArrayDeque`.

Итак, если мы встречаем открытую скобку, то помещаем ее в стек, если скобка не является открывающей, то достаем из стека то, что находится на вершине и проверяем закрывает ли она ее. Если нет - то сбалансированность нарушена и можно сразу возвращать `false`.

```java
public static boolean isBracerBalanced(String line) {
if (line == null) {
throw new IllegalArgumentException("Input can't be null");
}

if (line.isBlank()) {
return true;
}

Deque<Character> openBraces = new ArrayDeque<>();

for (char ch : line.toCharArray()) {
if (ch == '{' || ch == '[' || ch == '(') {
openBraces.add(ch);
} else {
if (openBraces.isEmpty()) {
return false;
}

char popped = openBraces.pollLast();

if (ch == ')') {
if (popped != '(') {
return false;
}
}

if (ch == ']') {
if (popped != '[') {
return false;
}
}

if (ch == '}') {
if (popped != '{') {
return false;
}
}
}
}

return openBraces.isEmpty();
}
```

### От обратного

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

В таком случае, можно избавиться от череды `if`-ов с `popped` проверкой, так как, если встречается не открывающая скобка, то из стека мы достанем либо ее же, либо это будет не сбалансированная строка.

```java
public static boolean isBracerBalanced(String line) {
if (line == null) {
throw new IllegalArgumentException("Input can't be null");
}

if (line.isBlank()) {
return true;
}

Deque<Character> stack = new ArrayDeque<>();

for (char ch : line.toCharArray()) {
if (ch == '{') {
stack.add('}');
} else if (ch == '[') {
stack.add(']');
} else if (ch == '(') {
stack.add(')');
} else if (stack.isEmpty() || stack.pollLast() != ch) {
return false;
}
}

return stack.isEmpty();
}
```
1 change: 1 addition & 0 deletions interview/algorithms/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

### Легкий уровень

* [Сбалансированность скобок](./easy/balanced_braces.md)
* [Количество повторов символов в строке](./easy/count_letters.md)
* [Сложение двух чисел представленных в виде списков](./easy/add_two_numbers.md)
* [Объединить два отсортированных массива](./easy/merge_two_sorted_arrays.md)
Expand Down

0 comments on commit 6b45e80

Please sign in to comment.