leetcode22——括号生成

题意

给定一个数字,表示括号"()"的对数,输出有效的匹配括号组合;

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

难点

如果可以构建出所有括号的组合,通过判断是否是左右括号的匹配,就可以输出所有正确的序列;

最开始感觉的难点在构建出所有的括号组合,一般回溯算法可以抽象成树形结构,使用树的深度优先遍历构建。这棵树从最开始的空到第一个元素可以选择左括号也可以选择右括号,第二个元素可以……,直到树的深度达到我们指定的括号个数的2倍,每一个根节点到达叶子节点的路径都是一个序列,这个序列需要被判断是否左右括号匹配,最终输出;

代码

1、首先是构建树形结构:

public List<String> generateParenthesis(int n) {
    List<String> res = new ArrayList<>();
    if (n <= 0) return res;
    dfs(n, "", res);
    return res;
}

private void dfs(int n, String path, List<String> res) {
    if (path.length() == 2 * n) {
        res.add(path);
        return;
    }

    dfs(n, path + "(", res);
    dfs(n, path + ")", res);
}

2、区分满足条件的序列:

public List<String> generateParenthesis(int n) {
    List<String> res = new ArrayList();
    dfs(n, "", res);
    Iterator<String> iterator = res.iterator();
    while (iterator.hasNext()) {
        String next = iterator.next();
        if (!isVaild(next)) {
            iterator.remove();
        }
    }

    for (String val : res) {
        if (!isVaild(val)) {
            res.remove(val);
        }
    }
    return res;
}

private boolean isVaild(String val) {
    Stack<Character> stack = new Stack<>();
    for (int i = 0; i < val.length(); i++) {
        if (val.charAt(i) == '(') {
            stack.push(val.charAt(i));
        } else {
            if (stack.isEmpty()) {
                return false;
            } else {
                stack.pop();
            }
        }
    }
    return stack.isEmpty();
}


public void dfs(int n, String path, List<String> res) {
    //这是一个基础的二叉树遍历的结果,深度遍历构造这样一个二叉树,能获取所有的组合
    if (path.length() == 2 * n) {
        res.add(path);
        return;
    }
    dfs(n, path + "(", res);
    dfs(n, path + ")", res);
}

这个解法的时间和空间复杂度很高,这个题目应该需要使用回溯+剪纸,后续进行补充;

posted @ 2021-10-29 16:07  精神小土豆  阅读(40)  评论(0)    收藏  举报