Code 生成括号

来源:互联网 发布:郴州办公软件培训班 编辑:程序博客网 时间:2024/06/07 05:06
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

原创粉丝点击