• 递归&回溯&剪枝-括号生成


    LCR 085. 括号生成 - 力扣(LeetCode)

    一. 根据题意,分析出符合要求的括号组合需要满足以下两个条件:

    1. 左括号数或者右括号数都不能超过 n;

    2. 从最左侧开始的每一个子集,不可以出现右括号数大于左括号数,例如:"( () ) ) (" 的子集:"( () ) ) "就出现了右括号书大于左括号数,这样是不符合规范的;

    二. 画决策图来分析递归过程: 

    以下图中的"左括号"和"右括号"指的是他们的数量!

     三. 考虑全局变量的使用:

    1. 使用全局变量 StringBuffer 来存储遍历过程的值;

    2. 使用全局变量 List 来存储每一次满足结果的String;

    3. 使用全局变量 left 和 right 来存储当前使用的左括号和右括号的数量;

    所以递归出口可以设置为 StringBuffer.length() == 2*n ;

    四. 针对上述提到的两个条件来进行剪枝操作;

    1. 右括号数小于左括号书的时候,才进行右括号数的添加:right < left;

    2. 左括号数和右括号数量小于n的时候,才进行添加;left < n;right < n;

     

    四. 回溯过程:

    当决策数在每一层进行左括号或者右括号添加完成之后,需要进行现场恢复操作,也就是把 StringBuffer 的最后一个字符删除;

    代码实现: 

    1. class Solution {
    2. List ret = new ArrayList<>();
    3. StringBuffer str = new StringBuffer();
    4. int left = 0;
    5. int right = 0;
    6. public List generateParenthesis(int n) {
    7. dfs(n);
    8. return ret;
    9. }
    10. public void dfs(int n){
    11. // 递归出口
    12. if(str.length() == n*2){
    13. ret.add(str.toString());
    14. return;
    15. }
    16. // 通过剪枝,符合条件的来添加左括号
    17. if(left < n){
    18. str.append("(");
    19. left++;
    20. dfs(n);
    21. // 回溯
    22. str.deleteCharAt(str.length()-1);
    23. left--;
    24. }
    25. // 通过剪枝,符合条件的来添加右括号
    26. if(right < left && right < n){
    27. str.append(")");
    28. right++;
    29. dfs(n);
    30. // 回溯
    31. str.deleteCharAt(str.length()-1);
    32. right--;
    33. }
    34. }
    35. }

  • 相关阅读:
    【ICLR23论文】Can CNNs Be More Robust Than Transformers?
    第七章 数学 AcWing 1586. 连续因子
    【EI会议征稿】第四届材料化学与复合材料国际学术会议(MCCM 2023)
    Echarts 教程二
    大数据基础架构选型
    AbstractExecutorService 抽象类
    操作系统【OS】进程的控制结构PCB
    记录--使用Vue开发Chrome插件
    基于随机森林的otto商品分类
    bean的生命周期
  • 原文地址:https://blog.csdn.net/weixin_69417428/article/details/136423653