LeetCode 22. 括号生成

该博客讨论了如何使用深度优先搜索(DFS)和剪枝策略来生成所有有效括号组合的问题。当给定括号对数n时,通过递归和回溯方法可以遍历所有可能的组合,并对无效组合进行剪枝,以确保结果的正确性。文章还提到了使用StringBuilder而非String进行字符串操作以提高效率,并详细解释了其构造方法和常用方法。此外,代码示例展示了如何实现这一算法,包括对非法字符串的剪枝条件。
摘要由CSDN通过智能技术生成

22. 括号生成        (dfs,剪枝,回溯,StringBuilder)

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

示例:

输入1:

    n = 3

输出1:

    ["((()))","(()())","(())()","()(())","()()()"]



输入2:

    n = 1

输出2:
    
    ["()"]

范围:

1 <= n <= 8

对于 n ,每一个结果字符串的长度都等于 2*n

可以用dfs遍历每一个结果字符串,对于不符合要求的结果字符串进行剪枝

代码:

public List<String> generateParenthesis(int n) {
    //初始化 List
    List<String> list = new ArrayList<String>();
    //如果 n=0 返回空 list
    if(n==0)return list;
    dfs(n,0,"",list);
    return list;
}

    //              数字n     计数     字符串        结果集
    public void dfs(int n,int num,String s,List<String> list){
        //如果 长度 = n*2 将结果添加进list,结束
        if(s.length() == n*2){
            list.add(s);
            return;
        }
        //添加 '(' 或者 ')'
        dfs(n, num+1, s + '(', list);
        dfs(n, num+1, s + ')', list);
    }

以上代码可以遍历出 n 时所有结果

例如 n = 2 时

["((((","((()","(()(","(())","()((","()()","())(","()))",")(((",")(()",")()(",")())","))((","))()",")))(","))))"]

而对于整体 dfs 像一颗二叉树,如图。 

 接下来只需要对那些不符合要求的进行剪枝即可

例如

        第一个以 ')' 开头的 return

        ')' 比 '(' 多的 return  等

则可以得出以下代码

class Solution {
    //主方法
    public List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<String>();
        if(n==0)return list;
        dfs(n,0,0,new StringBuilder(18),list);
        return list;
    }
    //dfs             n数   '(' 个数   ')' 个数        字符串        集合
    public void dfs(int n,int upper,int close,StringBuilder s,List<String> list){
        //如果第一个是以 ')' 开头,直接 return
        if(upper==0&&close==1){
            return;
        }
        //如果 ')' 个数比 '(' 个数多,或者 '(' 个数比 n 多,或者 ')' 个数比 n 多
        if(upper>n || close>n || close>upper){
            return;
        }
        //长度达到后,添加进集合中并退出递归
        if(s.length() == n*2){
            list.add(s.toString());
            return;
        }
        //添加 '('
        dfs(n, upper+1, close, s.append('('), list);
        //回溯时减去最后一位添加的
        s.deleteCharAt(s.length()-1);
        //添加 ')'
        dfs(n, upper, close+1, s.append(')'), list);
        //回溯时减去最后一位
        s.deleteCharAt(s.length()-1);

    }
}

 这里使用 StringBuilder 而不使用 String,是因为StringBuilder的效率要比String高。

(在CSDN本题提交中,用StringBuilder执行用时为:0 ms,而String执行用时为:1 ms)

同时也学习了一些 StringBuilder 的方法。

构造方法:

        StringBuilder()                          无参构造,初始容量为16

        StringBuilder(int capacity)         指定初始容量

        StringBuilder(String str)            初始内容为指定字符串

方法:

        append(char a)                        向字符串最后添加值,有stirng,char等方法重载..

        charAt(int index)                       类似String的charAt()方法

        delete(int start,int end)              移出 start(包括) 至 end(不包括)

        deleteCharAt(int index)              移出index的字符

        length()                                     获取有内容的长度

        

在补充几个

        substring(int start,int end)          获取 start(包括) 至 end(不包括)

        insert(int offset,Object obj)        插入在offset中,类似String

        reverse()                                  反转字符串

        trimToSize()                              将StringBuffer对象的中存储空间缩⼩到和字符串长度⼀样的长度,减少空间的浪费。

        setCharAt()                               修改对象中索引值为index位置的字符为新的字符ch

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值