剑指 Offer II 085. 生成匹配的括号(22. 括号生成)

题目:

思路:

【1】回溯的方式

【2】按括号序列的长度递归

任何一个括号序列都一定是由 '(' 开头,并且第一个 '(' 一定有一个唯一与之对应的 ')'。
这样一来,每一个括号序列可以用 (a)b 来表示,其中 a 与 b 分别是一个合法的括号序列(可以为空)。

那么,要生成所有长度为 2n 的括号序列,我们定义一个函数 generate(n)\ 来返回所有可能的括号序列。
那么在函数 generate(n) 的过程中:
    我们需要枚举与第一个 '(' 对应的 ')' 的位置 2i+1;
    递归调用 generate(i) 即可计算 a 的所有可能性;
    递归调用 generate(n−i−1) 即可计算 bbb 的所有可能性;
    遍历 a 与 b 的所有可能性并拼接,即可得到所有长度为 2n2n2n 的括号序列。

为了节省计算时间,我们在每次 generate(i) 函数返回之前,把返回值存储起来,
下次再调用 generate(i) 时可以直接返回,不需要再递归计算。

 

代码展示:

按括号序列的长度递归:

//时间7 ms击败11.46%
//内存41.4 MB击败69.69%
class Solution {
    ArrayList[] cache = new ArrayList[100];

    public List<String> generate(int n) {
        if (cache[n] != null) {
            return cache[n];
        }
        ArrayList<String> ans = new ArrayList<String>();
        if (n == 0) {
            ans.add("");
        } else {
            for (int c = 0; c < n; ++c) {
                for (String left: generate(c)) {
                    for (String right: generate(n - 1 - c)) {
                        ans.add("(" + left + ")" + right);
                    }
                }
            }
        }
        cache[n] = ans;
        return ans;
    }

    public List<String> generateParenthesis(int n) {
        return generate(n);
    }
}

 

回溯的方式:

//时间1 ms击败64.52%
//内存41.8 MB击败16.31%
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n == 0) return res;
        dfs(n,0,new StringBuffer(),res);
        return res;
    }

    private void dfs(int left_b, int right_b, StringBuffer path, List<String> res) {
        if (left_b == 0 && right_b == 0) {
            res.add(path.toString());
            return;
        }

        if (left_b > 0){
            dfs(left_b - 1,right_b + 1,path.append("("),res);
            path.deleteCharAt(path.length()-1);
        }
        if (right_b > 0){
            dfs(left_b,right_b - 1,path.append(")"),res);
            path.deleteCharAt(path.length()-1);
        }
    }
}


//直接用String更直观点
//时间1 ms击败75.56%
//内存41.6 MB击败38.2%
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n == 0) return res;
        dfs(n,0,"",res);
        return res;
    }

    private void dfs(int left_b, int right_b, String path, List<String> res) {
        if (left_b == 0 && right_b == 0) {
            res.add(path);
            return;
        }

        if (left_b > 0){
            dfs(left_b - 1,right_b + 1,path+"(",res);
        }
        if (right_b > 0){
            dfs(left_b,right_b - 1,path+")",res);
        }
    }
}

 

posted @ 2023-04-04 12:35  忧愁的chafry  阅读(10)  评论(0编辑  收藏  举报