【LeetCode】22. 括号生成

链接:

https://leetcode-cn.com/problems/generate-parentheses

描述:

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例:
输入:n = 3
输出:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]

vector<string> generateParenthesis(int n) {}

思路:暴力法

用递归生成所有的序列:
长度为 \(n-1\) 的序列后加上 '(' 或者 ')',就可以得到长度为 \(n\) 的序列。

检查序列是否有效:
设置一个变量 \(count\) 记录未匹配的左括号的数量,
遍历序列中的每一个元素 \(c\)
 若 \(c\) 为 '(',\(count\) 值加一
 若 \(c\) 为 ')',\(count\) 值减一
  如果 \(count\) 的值小于零,则序列无效
最后,若 \(count\) 为零则序列有效,否则为无效

C++

展开后查看
class Solution {
public:
    vector<string> generateParenthesis(int n) {   
        vector<string> result;
        string current;
        generate_all(current, n * 2, result);
        return result;
    }

    void generate_all(string& current, int n, vector<string>& result){
        if(n == current.size()){
            if(valid(current)){
                result.push_back(current);
            }
            return;
        }
        current.push_back('(');
        generate_all(current, n, result);
        current.pop_back();
        current.push_back(')');
        generate_all(current, n, result);
        current.pop_back();
    }

    bool valid(string& s){
        int count = 0;
        for(char c : s){
            if(c == '('){
                count++;
            }else{
                count--;
                if(count < 0){
                    return false;
                }
            }
        }
        return count == 0;
    }
};

Java

展开后查看
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> result = new ArrayList();
        generateAll(new StringBuilder(), n * 2, result);
        return result;
    }
    void generateAll(StringBuilder current, int n, List<String> result){
        if(current.length()== n){
            if(valid(current.toString())){
                result.add(current.toString());
            }
        }else{
            current.append('(');
            generateAll(current, n, result);
            current.deleteCharAt(current.length() - 1);
            current.append(')');
            generateAll(current, n, result);
            current.deleteCharAt(current.length() - 1);
        }
    }
    boolean valid(String current){
        int count = 0;
        for(int i = 0; i < current.length(); i++){
            if(current.charAt(i) == '('){
                count++;
            }else{
                count--;
                if(count < 0){
                    return false;
                }
            }
        }
        return count == 0;
    }
}

思路:回溯法

改进上面方法:在生成序列的过程中,根据当前情况只继续生成有效的序列

如果左括号的数量小于 \(n\) ,可以再添加一个左括号
如果右括号的数量小于左括号的数量,可以再添加一个右括号

时间复杂度:\(O(n^2)\),空间复杂度:\(O(1)\)

C++

展开后查看
class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> result;
        string current;
        backTrack(result, current, 0, 0, n);
        return result;
    }
    void backTrack(vector<string>& result, string& current, int left, int right, int n){
        if(current.size() == n * 2){
            result.push_back(current);
            return;
        }
        if(left < n){
            current.push_back('(');
            backTrack(result, current, left + 1, right, n);
            current.pop_back();
        }
        if(right < left){
            current.push_back(')');
            backTrack(result, current, left, right + 1, n);
            current.pop_back();
        }
    }
};

Java

展开后查看
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> result = new ArrayList<>();
        backTrack(result, new StringBuilder(), 0, 0, n);
        return result;
    }
    void backTrack(List<String> result, StringBuilder current, int left, int right, int n){
        if(current.length() == n * 2){
            result.add(current.toString());
            return;
        }
        if(left < n){
            current.append('(');
            backTrack(result, current, left + 1, right, n);
            current.deleteCharAt(current.length() - 1);
        }
        if(right < left){
            current.append(')');
            backTrack(result, current, left, right + 1, n);
            current.deleteCharAt(current.length() - 1);
        }
    }
}
posted @ 2020-06-21 08:52  CrazyBlogs  阅读(68)  评论(0编辑  收藏  举报