括号生成

题目描述

来源于 https://leetcode-cn.com/

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

例如,给出 n = 3,生成结果为:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

解法:

用一个空字符串,先尝试添加左括号,再添加右括号。

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> result;
        string path;
        if (n > 0) {
            generate(n, path, result, 0, 0);
        }
        return result;
    }

    static void generate(int n, string &path, vector<string> &result, int l, int r) {
        if (l == n) {
            string s(path);
            s.append(n - r, ')');
            result.push_back(::move(s));
            return;
        }

        path.push_back('(');
        generate(n, path, result, l + 1, r);
        path.pop_back();

        if (l > r) {
            path.push_back(')');
            generate(n, path, result, l, r + 1);
            path.pop_back();
        }
    }
};

也可以采用迭代的方法,每次加入一个括号。在上一步的每个结果之上,如果左括号还有余下的,就可以添加左括号,如果已经添加的左括号数大于右括号数,就可以添加一个右括号。

因此,需要使用一个数组保存当前的结果,使用另外一个数组来记录左括号的数量。

class Solution {
public:
vector<string> generateParenthesis(int n) {
        vector<string> parentheses = {"("};
        vector<int> left_counts = {1};
        vector<string> new_parentheses;
        vector<int> new_left_counts;
        
        for (int i = 1; i < n * 2; i++) {
            new_parentheses.clear();
            new_left_counts.clear();
            new_parentheses.reserve(parentheses.size() * 2);
            new_left_counts.reserve(parentheses.size() * 2);

            for (int j = 0; j < parentheses.size(); j++) {
                string &str = parentheses[j];
                int left = left_counts[j];
                int right = str.size() - left;

                if (left < n) {
                    new_parentheses.emplace_back(str + "(");
                    new_left_counts.emplace_back(left + 1);
                }

                if (left > right) {
                    new_parentheses.emplace_back(str + ")");
                    new_left_counts.emplace_back(left);
                }
            }
            parentheses.swap(new_parentheses);
            left_counts.swap(new_left_counts);
        }
        return parentheses;
    }
};