Code 生成括号

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"

在LeetCode中有关括号的题共有三道,除了这一道的另外两道是 Valid Parentheses 验证括号和 Longest Valid Parentheses 最长有效括号,这道题给定一个数字n,让生成共有n个括号的所有正确的形式,对于这种列出所有结果的题首先还是考虑用递归Recursion来解,由于字符串只有左括号和右括号两种字符,而且最终结果必定是左括号3个,右括号3个,所以我们定义两个变量left和right分别表示剩余左右括号的个数,如果在某次递归时,左括号的个数大于右括号的个数,说明此时生成的字符串中右括号的个数大于左括号的个数,即会出现’)(‘这样的非法串,所以这种情况直接返回,不继续处理。如果left和right都为0,则说明此时生成的字符串已有3个左括号和3个右括号,且字符串合法,则存入结果中后返回。如果以上两种情况都不满足,若此时left大于0,则调用递归函数,注意参数的更新,若right大于0,则调用递归函数,同样要更新参数。代码如下:

C++ 解法一:

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        generateParenthesisDFS(n, n, "", res);
        return res;
    }
    void generateParenthesisDFS(int left, int right, string out, vector<string> &res) {
        if (left > right) return;
        if (left == 0 && right == 0) res.push_back(out);
        else {
            if (left > 0) generateParenthesisDFS(left - 1, right, out + '(', res);
            if (right > 0) generateParenthesisDFS(left, right - 1, out + ')', res);
        }
    }
};

Java 解法一:

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<String>();
        helper(n, n, "", res);
        return res;
    }
    void helper(int left, int right, String out, List<String> res) {
        if (left < 0 || right < 0 || left > right) return;
        if (left == 0 && right == 0) {
            res.add(out);
            return;
        }
        helper(left - 1, right, out + "(", res);
        helper(left, right - 1, out + ")", res);
    }
}

再来看那一种方法,这种方法是CareerCup书上给的方法,感觉也是很巧妙的一种方法,这种方法的思想是找左括号,每找到一个左括号,就在其后面加一个完整的括号,最后再在开头加一个(),就形成了所有的情况,需要注意的是,有时候会出现重复的情况,所以我们用set数据结构,好处是如果遇到重复项,不会加入到结果中,最后我们再把set转为vector即可,参见代码如下::

n=1: ()

n=2: (()) ()()

n=3: (()()) ((())) ()(()) (())() ()()()

C++ 解法二:

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        set<string> t;
        if (n == 0) t.insert("");
        else {
            vector<string> pre = generateParenthesis(n - 1);
            for (auto a : pre) {
                for (int i = 0; i < a.size(); ++i) {
                    if (a[i] == '(') {
                        a.insert(a.begin() + i + 1, '(');
                        a.insert(a.begin() + i + 2, ')');
                        t.insert(a);
                        a.erase(a.begin() + i + 1, a.begin() + i + 3);
                    }
                }
                t.insert("()" + a);
            }
        }
        return vector<string>(t.begin(), t.end());
    }
};

Java 解法二:

public class Solution {
    public List<String> generateParenthesis(int n) {
        Set<String> res = new HashSet<String>();
        if (n == 0) {
            res.add("");
        } else {
            List<String> pre = generateParenthesis(n - 1);
            for (String str : pre) {
                for (int i = 0; i < str.length(); ++i) {
                    if (str.charAt(i) == '(') {
                        str = str.substring(0, i + 1) + "()" + str.substring(i + 1, str.length());
                        res.add(str);
                        str = str.substring(0, i + 1) +  str.substring(i + 3, str.length());
                    }
                }
                res.add("()" + str);
            }
        }
        return new ArrayList(res);
    }
}

类似题目:
Remove Invalid Parentheses
Different Ways to Add Parentheses
Longest Valid Parentheses
Valid Parentheses

其它1:检测,如果左括号的个数到了n,则for循环补齐所有右括号,时间复杂度是不是会减低很多?因为剪枝减了将近一半。

public class Solution
{
    public List<string> GenerateParenthesis(int n)
    {
        var result = new List<string>();
        if (n < 1) return result;

        var oneResult = new StringBuilder();
        oneResult.Append("(");
        GenerateParenthesisDFS(1, 0, n, result, oneResult);

        return result;

    }

    private void GenerateParenthesisDFS(  
                            int leftParenthesisCount, int rightParenthesisCount, int n,
                            List<string> result, StringBuilder oneResult)
    {
        if (leftParenthesisCount == n)
        {  
            string tempResult = oneResult.ToString();
            for (int i = 0; i < n - rightParenthesisCount; i++)
            {
                tempResult += ")";
            }

            result.Add(tempResult);
            return;
        }
        else if (rightParenthesisCount > leftParenthesisCount)
        {
            return;
        }
        else
        {
            oneResult.Append("(");
            GenerateParenthesisDFS(leftParenthesisCount + 1, rightParenthesisCount, n, result, oneResult);

            oneResult.Remove(oneResult.Length - 1, 1);
            oneResult.Append(")");
            GenerateParenthesisDFS(leftParenthesisCount, rightParenthesisCount + 1, n, result, oneResult);

            oneResult.Remove(oneResult.Length - 1, 1);

        }
    }
}

其它2:提前剪枝

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        // Write your code here
        vector<string> res;
        string out;
        dfs(n, 0, 0, out, res);
        return res;
    }
    void dfs(int n, int left, int right, string &out, vector<string> &res) {
        if (left < n) { //Keep 塞左括号
            out.push_back('(');
            dfs(n, left + 1, right, out, res);
            out.pop_back();
        }
        if (right < left) { //避免出现右括号多余左括号的情况
            out.push_back(')');
            dfs(n, left, right + 1, out, res);
            out.pop_back();
        }
        if (out.size() == n * 2)
            res.push_back(out);
    }
};

转自:http://www.cnblogs.com/grandyang/p/4444160.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值