LeetCode 22.括号生成

1,039 阅读1分钟

一、题目

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

示例:

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

二、方法一

我们将一对括号()看做一个整体。

要求 n对括号 的有效组合,假设我们已知 n-1对括号 的有效组合,只需要将一对括号()插入其中的各个位置就可以得到。

另外,由于得到的结果有可能会有重复,我们采用 HashSet 去重。

public List<String> generateParenthesis2(int n) {
    List<String> list=new ArrayList<>();
    String onePair="()";
    list.add(onePair);
    if(n==1)
        return list;
    for(int i=1;i<n;i++) {
        HashSet<String> set=new HashSet<>();
        for(String pair:list) {
            //i对括号,包括2*i个括号,也就2*i+1个可以插入的位置
            for(int j=0;j<=2*i;j++) {
                //插入括号
                StringBuilder sb=new StringBuilder(pair);
                String tempString=sb.insert(j, onePair).toString();
                set.add(tempString);
            }
        }
        list=new ArrayList<>(set);
    }
    return list;
}

三、方法二

这里我们采用“减法”,left 代表剩余的左括号数量,right 代表剩余的右括号数量,以 n=2 为例,画树形结构图如下:

WX20210814-172132@2x.png 从中可以看出,为了生成 有效的 括号组合:

  • 剩余的左括号和右括号数量相等的时候,只能填入左括号。
  • 剩余的左括号数量小于右括号的时候,既可以填入左括号,也可以填入右括号。
  • 当剩余的左括号和剩余的右括号数量都为0时结算。

我们只要采用 深度优先搜索 方法,就可以得到相应的括号组合。

class Solution {
    List<String> list=new ArrayList<>();
    public List<String> generateParenthesis(int n) {
        dfs("", n,n);
        return list;
    }
    /**
     * 根据剩余左括号数,右括号数,生成一个包含“n对括号”的有效字符串
     * @param str 已经填入的字符串
     * @param left 剩余的左括号数量
     * @param right 剩余的右括号数量
     */
    public void dfs(String str,int left,int right) {
        if(left==0&&right==0) {
            list.add(str);
            return;
        }
        if(left==right) {
            dfs(str+"(",left-1,right);
        }else {	
            if(left>0) {
                dfs(str+"(", left-1, right);
            }
            dfs(str+")", left, right-1);
        }
    }
}

qrcode2.png