[Leetcode] Generate Parentheses

Generate Parentheses 题解

题目来源:https://leetcode.com/problems/generate-parentheses/description/


Description

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

Example

For example, given n = 3, a solution set is:


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

Solution

class Solution {
private:
    void addPare(vector<string>& res, string str, int leftNeed, int rightNeed) {
        if (leftNeed == 0 && rightNeed == 0) {
            res.push_back(str);
        } else {
            if (leftNeed > 0)
                addPare(res, str + '(', leftNeed - 1, rightNeed + 1);
            if (rightNeed > 0) {
                addPare(res, str + ')', leftNeed, rightNeed - 1);
            }
        }
    }
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        if (n <= 0)
            return res;
        addPare(res, "", n, 0);
        return res;
    }
};

解题描述

这道题题意是,求出包含n对括号的合法(合法即满足编译要求)括号串。上面给出的做法是递归的方法:

  • 初始状态下,左括号需要的数目leftNeed = n和右括号需要的数目rightNeed = 0
  • 每次添加上左括号则leftNeed要自减,但是rightNeed要自增(左右匹配)
  • 每次添加上右括号则rightNeed要自减
  • leftNeedrightNeed均为0的时候说明括号串已经生成,可以添加到结果

评论区还给出了这道题的迭代方法,主要的思想是DP:n对括号的情况,是由n - 1,n - 2,... ,1对括号的情况组合起来的。所以可以从1开始一直往n进行递推:


class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<vector<string> > dp(n + 1, vector<string>());
        dp[0] = vector<string>{""};
        int i, j;
        for (i = 1; i <= n; i++) {
            for (j = 0; j < i; j++)
                for (auto first : dp[j])
                    for (auto second : dp[i - 1 - j]) {
                        auto temp = '(' + first + ')' + second;
                        dp[i].push_back(temp);
                    }
        }
        return dp[n];
    }
};

算法的关键在于temp = '(' + first + ')' + second

  • firstsecond是n之前的2中互补的情况,即括号对数之和为n - 1,再加上一对括号就是n对括号的情况
  • first的括号对数是升序,second的括号对数是降序,这样就能遍历所有的组合情况。
原文地址:https://www.cnblogs.com/yanhewu/p/8392577.html