括号生成问题【2021-12-16】

1. 核心题目

1.1 题目描述

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

1.2 示例

条件 1 <= n <= 8

1.2.1 例1

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

1.2.2 例2

输入:n = 1
输出:["()"]

1.3 免责声明

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
本题题目源自力扣,这里声明地址,不做商用,只做学习使用,特注免责。

2.题目解析

2.1 初步思考

本题如果考虑不到二叉树的话,基本就只能暴力解决了。【暴力解的结果也是一个满二叉树的排除解法】
至于为什么需要考虑二叉树,在笔者看来,有以下的原因:

  • 因为每次增加括号填充的时候,只能填写左括号以及右括号。
  • 需要得到所有情况的结果集,很类似于二叉树的路径。

2.2 具体思考

我们来看一下这里绘制的图 当 n = 2 的时候,我们将二岔树的情况画一下,就如下图所示:
n=2的满置二岔情况

图解: 两个数字

  • 左侧代表左括号剩余的数量
  • 右侧代表右括号剩余的数量
  • 每一级减少的数字,代表已经添加了对应的括号了。

通过手绘如此的二叉树 我们发现填充二岔树的条件有以下几点:

  • 左侧的数字大于右侧的时候 终止本条二岔树 ==> 即【左侧的数字小于等于右侧的数字】
  • 两侧的的数字都大于等于0
  • 当两侧数字都等于0的时候本轮就得出一个结果,将路径放入到结果集之中。

因此 依照下列思路就能完成本题的解答了。

  1. 需要依据左侧括号和右侧括号剩余的数量来走完所有的路径。
  2. 只有右括号大于等于左侧括号的时候才进行下一个结点的操作。
  3. 两个括号的数量都大于等于0的时候才进行下一个结点的操作。
  4. 当两个括号的数量都为0的时候,将路径输出到结果集之中。
  5. 自己的子节点的操作则为左侧计数减1 左侧括号加1;右侧计数减1 右侧括号加1。

2.3 具体编码

依据上述思路 具体得到的编码未下列编码

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ret = new ArrayList();         // 存放结果值的
        dfs(ret, n, n, "");                         // 采用深度优先的算法 填充最终的结果
        return ret;
    }
    /**
    * 深度优先 得到符合要求的内容,并将内容存入结果集之中。
    * ret: 要填充的结果表
    * l_n: 左侧剩余的括号
    * r_n:右侧剩余的括号
    * pre: 存储当前前面的路径的方法
	*/
    public void dfs(List<String> ret, int l_n, int r_n, String pre){
        if(l_n==0&&r_n==0){     		// 左括号和右括号都没有剩余的话 则填充ret即可
            ret.add(pre);
        }else if(l_n<=r_n&&l_n>=0){     // 注意:右边的剩余括号数量要大于左边剩余括号的数量才合法 左侧的括号数量也不能小于0
            dfs(ret, l_n-1, r_n, pre+"(");          // 填充左括号的情况 【左侧计数-1,左侧加括号】
            dfs(ret, l_n, r_n-1, pre+")");          // 填充右括号的情况 【右侧计数-1, 右侧加括号】
        } // 其他的情况都非法
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值