План курса / Все задачи / Алгоритмы и структуры данных
Расстановка скобок
средне
Дано число n, обозначающее количество пар круглых скобок. Напишите функцию, которая генерирует все уникальные комбинации корректно составленных скобочных последовательностей из n пар.
Пример 1:
Ввод: n = 2
Вывод: ["(())","()()"]
Пример 2:
Ввод: n = 1
Вывод: ["()"]
Ограничения:
n >= 1
class Solution {
public static void BruteForce(int n, int balance, List<char> currParentheses, List<string> allParentheses) {
// balance < 0 - число закрывающих больше, чем открывающих,
// тогда последовательность некорректна
// balance > n - currParentheses.Count - не хватит закрывающих скобок,
// чтобы сделать последовательность корректной
if (balance < 0 || balance > n - currParentheses.Count) {
return;
}
if (balance == 0 && currParentheses.Count == n) {
// список превратили в строку и добавили в ответ
allParentheses.Add(new string(currParentheses.ToArray()));
return;
}
// перебираем все возможные варианты
foreach (var brace in new[] { ('(', balance + 1), (')', balance - 1) }) {
currParentheses.Add(brace.Item1);
BruteForce(n, brace.Item2, currParentheses, allParentheses);
currParentheses.RemoveAt(currParentheses.Count - 1);
}
}
public static List<string> GenerateBrackets(int n) {
List<string> allParentheses = new List<string>();
List<char> currParentheses = new List<char>();
BruteForce(n * 2, 0, currParentheses, allParentheses);
return allParentheses;
}
}
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void bruteForce(int n, int balance, vector<char>& curr_parentheses, vector<string>& all_parentheses) {
// balance < 0 - число закрывающих больше, чем открывающих,
// тогда последовательность некорректна
// balance > n - curr_parentheses.size() - не хватит закрывающих скобок,
// чтобы сделать последовательность корректной
if (balance < 0 || balance > n - curr_parentheses.size()) {
return;
}
if (balance == 0 && curr_parentheses.size() == n) {
// список превратили в строку и добавили в ответ
all_parentheses.push_back(string(curr_parentheses.begin(), curr_parentheses.end()));
return;
}
// перебираем все возможные варианты
for (auto [brace, new_balance] : vector<pair<char, int>>{{'(', balance + 1}, {')', balance - 1}}) {
curr_parentheses.push_back(brace);
bruteForce(n, new_balance, curr_parentheses, all_parentheses);
curr_parentheses.pop_back();
}
}
vector<string> generateBrackets(int n) {
vector<string> all_parentheses;
vector<char> curr_parentheses;
bruteForce(n * 2, 0, curr_parentheses, all_parentheses);
return all_parentheses;
}
package main
func bruteForce(n, balance int, currParentheses []rune, allParentheses *[]string) {
// balance < 0 - число закрывающих больше, чем открывающих,
// тогда последовательность некорректна
// balance > n - len(currParentheses) - не хватит закрывающих скобок,
// чтобы сделать последовательность корректной
if balance < 0 || balance > n - len(currParentheses) {
return
}
if balance == 0 && len(currParentheses) == n {
// список превратили в строку и добавили в ответ
*allParentheses = append(*allParentheses, string(currParentheses))
return
}
// перебираем все возможные варианты
for _, brace := range []struct {
Brace rune
NewBalance int
}{
{'(', balance + 1},
{')', balance - 1},
} {
currParentheses = append(currParentheses, brace.Brace)
bruteForce(n, brace.NewBalance, currParentheses, allParentheses)
currParentheses = currParentheses[:len(currParentheses)-1]
}
}
func generateBrackets(n int) []string {
var allParentheses []string
bruteForce(n*2, 0, []rune{}, &allParentheses)
return allParentheses
}
import java.util.ArrayList;
import java.util.List;
public class Solution {
// Рекурсивный метод для генерации всех корректных скобочных последовательностей
private static void bruteForce(int n, int balance, List<Character> currParentheses, List<String> allParentheses) {
// balance < 0 - число закрывающих больше, чем открывающих,
// тогда последовательность некорректна
// balance > n - currParentheses.size() - не хватит закрывающих скобок,
// чтобы сделать последовательность корректной
if (balance < 0 || balance > n - currParentheses.size()) {
return;
}
if (balance == 0 && currParentheses.size() == n) {
// Преобразуем список символов в строку и добавляем в результат
StringBuilder sb = new StringBuilder();
for (char c : currParentheses) {
sb.append(c);
}
allParentheses.add(sb.toString());
return;
}
// Перебираем все возможные варианты
char[] braces = {'(', ')'};
int[] balanceChanges = {1, -1};
for (int i = 0; i < braces.length; i++) {
currParentheses.add(braces[i]);
bruteForce(n, balance + balanceChanges[i], currParentheses, allParentheses);
currParentheses.remove(currParentheses.size() - 1);
}
}
// Метод для генерации всех корректных скобочных последовательностей длины 2n
public static List<String> generateBrackets(int n) {
List<String> allParentheses = new ArrayList<>();
bruteForce(n * 2, 0, new ArrayList<>(), allParentheses);
return allParentheses;
}
}
from typing import *
def brute_force(n, balance, curr_parentheses, all_parentheses):
# balance < 0 - число закрывающих больше, чем открывающих,
# тогда последовательность некорректна
# balance > n - len(currParentheses) - не хватит закрывающих скобок,
# чтобы сделать последовательность корректной
if balance < 0 or balance > n - len(curr_parentheses):
return
if balance == 0 and len(curr_parentheses) == n:
# список превратили в строку и добавили в ответ
all_parentheses.append("".join(curr_parentheses))
return
# перебираем все возможные варианты
for brace, new_balance in [["(", balance + 1], [")", balance - 1]]:
curr_parentheses.append(brace)
brute_force(n, new_balance, curr_parentheses, all_parentheses)
curr_parentheses.pop()
def generate_brackets(n: int) -> List[str]:
all_parentheses = []
brute_force(n * 2, 0, [], all_parentheses)
return all_parentheses
export function bruteForce(n, balance, currParentheses, allParentheses) {
// balance < 0 - число закрывающих больше, чем открывающих,
// тогда последовательность некорректна
// balance > n - currParentheses.length - не хватит закрывающих скобок,
// чтобы сделать последовательность корректной
if (balance < 0 || balance > n - currParentheses.length) {
return;
}
if (balance === 0 && currParentheses.length === n) {
// список превратили в строку и добавили в ответ
allParentheses.push(currParentheses.join(''));
return;
}
// перебираем все возможные варианты
for (const [brace, newBalance] of [['(', balance + 1], [')', balance - 1]]) {
currParentheses.push(brace);
bruteForce(n, newBalance, currParentheses, allParentheses);
currParentheses.pop();
}
}
export function generateBrackets(n) {
const allParentheses = [];
bruteForce(n * 2, 0, [], allParentheses);
return allParentheses;
}
Оценка сложности
Время: O(n * 4n) или более точно O(n * Cn), где Cn - n-ое число Каталана
Память: O(n * 4n) или более точно O(n * Cn), где Cn - n-ое число Каталана