程序员面试金典 8.9

Parens:生成n对括号的所有合法排列。

可以根据n - 1对括号的结果,将第n对括号插入到任意的合法位置,但是这会出现重复的结果,而且判重很麻烦,需要通过完整的字符串比较才可以。

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        genCombnation(n);
        return vector<string>(Comb.begin(), Comb.end());
    }
private:
    set<string> Comb;
    void genCombnation(int n)
    {
        if(n == 0){
            Comb.insert("");
            return;
        }
        genCombnation(n - 1);
        vector<string> subComb(Comb.begin(), Comb.end());
        Comb.clear();
        for(size_t i = 0; i < subComb.size(); i++)
        {
            const string &strComb = subComb[i];
            for(size_t pos = 0; pos < strComb.size(); pos++)
            {
                Comb.insert(strComb.substr(0, pos) + "()" + strComb.substr(pos));
            }
            Comb.insert(strComb + "()");
        }
    }
};

上面的解法太蠢了,在判重上费了很多精力。更好的解法是依次在每一个位置上放置左括号或者右括号:

  • 只要还有左括号,就可以放置左括号
  • 只有剩下的右括号比左括号多时才可以放置右括号
class Solution {
public:
    vector<string> generateParenthesis(int n) {
        genCombination(n, n);
        return Comb;
    }
private:
    vector<string> Comb;
    string res;
    void genCombination(int leftRem, int rightRem)
    {
        if(leftRem == 0 && rightRem == 0){
            Comb.push_back(res);
            return;
        }
        if(leftRem > 0){
            res.push_back('(');
            genCombination(leftRem - 1, rightRem);
            res.pop_back();
        }
        if(rightRem > leftRem){
            res.push_back(')');
            genCombination(leftRem, rightRem - 1);
            res.pop_back();
        }
    }
};

你可能感兴趣的:(《程序员面试金典》)