• 力扣22. 括号生成


    22. 括号生成

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

    示例:

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

    思路:dfs 回溯

    1. 产生有效解的情况是left和right均等于n

    2. 如果left < right, 说明当前字符串中右括号数多于左括号数,这是不不符合要求的,可以提前终止

    3. 如果left < n, 说明还有剩余的左括号没用完,可以继续递归左括号

    4. 如果right < n, 说明还有剩余的右括号没用完,还可以继续递归右括号

    做加法:

     1 class Solution {
     2     public List<String> generateParenthesis(int n) {
     3         // dfs回溯
     4         List<String> res = new ArrayList<String>();
     5         if(n == 0)
     6             return res;
     7        dfs(res, 0, 0,n, "");
     8        return res;
     9     }
    10 
    11     public void dfs(List<String> res, int left, int right, int n, String curStr){
    12         // 如果left和right都等于n了,说明已经生产了一个解
    13         if(left == n && right == n){
    14             res.add(curStr);
    15             return;
    16         }
    17         // 剪枝,如果left < right, 说明当前字符串中右括号数多于左括号数,这是不不符合要求的,可以提前终止
    18         if(left < right){
    19             return;
    20         }
    21 
    22         // 如果左括号数小于n说明还可以继续递归左括号
    23         if(left < n){
    24             dfs(res, left + 1, right, n, curStr + "(");
    25         }
    26 
    27         // 如果右括号小于n,说明还可以继续递归右括号
    28         if(right < n){
    29             dfs(res, left, right + 1, n, curStr + ")");
    30         }
    31     }
    32 }    

    复杂度分析

    上面的程序是对left 和 right 做加法,这里写个做减法的程序:

     1 class Solution {
     2     public List<String> generateParenthesis(int n) {
     3         // dfs回溯
     4 
     5         List<String> res = new ArrayList<String>();
     6         if(n == 0)
     7             return res;
     8        dfs(res, n, n,n, "");
     9        return res;
    10     }
    11 
    12     public void dfs(List<String> res, int left, int right, int n, String curStr){
    13         // 如果left和right都等于n了,说明已经生产了一个解
    14         if(left == 0 && right == 0){
    15             res.add(curStr);
    16             return;
    17         }
    18         // 剪枝,如果left > right, 说明当前字符串中右括号数多于左括号数,这是不不符合要求的,可以提前终止
    19         if(left > right){
    20             return;
    21         }
    22 
    23         // 如果左括号数大于0,说明还可以继续递归左括号
    24         if(left > 0){
    25             dfs(res, left - 1, right, n, curStr + "(");
    26         }
    27 
    28         // 如果右括号大于0,说明还可以继续递归右括号
    29         if(right > 0){
    30             dfs(res, left, right - 1, n, curStr + ")");
    31         }
    32     }
    33 }

    使用标准的回溯,

    上面两个程序其实是利用了String的不可变性,每个对 curStr 加上左右括号后其实对当前层次的curStr是没有影响的,相当于curStr自动回溯了,这里用StringBuilder代替String,标准的写一遍回溯,加深回溯的印象

     1 class Solution {
     2     public List<String> generateParenthesis(int n) {
     3         // dfs回溯
     4 
     5         List<String> res = new ArrayList<String>();
     6         if(n == 0)
     7             return res;
     8         StringBuilder curStr = new StringBuilder();
     9        dfs(res, n, n,n, curStr);
    10        return res;
    11     }
    12 
    13     public void dfs(List<String> res, int left, int right, int n, StringBuilder curStr){
    14         // 如果left和right都等于n了,说明已经生产了一个解
    15         if(left == 0 && right == 0){
    16             res.add(curStr.toString());
    17             return;
    18         }
    19         // 剪枝,如果left > right, 说明当前字符串中右括号数多于左括号数,这是不不符合要求的,可以提前终止
    20         if(left > right){
    21             return;
    22         }
    23 
    24         // 如果左括号数大于0,说明还可以继续递归左括号
    25         if(left > 0){
    26             curStr.append("(");
    27             dfs(res, left - 1, right, n, curStr);
    28             curStr.deleteCharAt(curStr.length() - 1); // 回溯到添加前的转态
    29         }
    30 
    31         // 如果右括号大于0,说明还可以继续递归右括号
    32         if(right > 0){
    33             curStr.append(")");
    34             dfs(res, left, right - 1, n, curStr);
    35             curStr.deleteCharAt(curStr.length() - 1);       // 回溯到添加前的转态
    36         }
    37     }
    38 }

    思路来源:

    https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/

  • 相关阅读:
    Windows 2008 server + IIS 7 设置身份模拟(ASP.NET impersonation)
    记录windows操作系统启动日志
    C# 重启计算机的问题
    AcWing 1086 恨7不是妻
    AcWing 1084. 数字游戏 II
    AcWing 1083. Windy数
    golang学习笔记 生成JSON及解析JSON 清明
    WEB前端底层知识之浏览器是如何工作的(2)渲染引擎
    ASP.NET MVC Razor 输出没有编码的HTML字符串
    ext.grid的配置属性和方法
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12939905.html
Copyright © 2020-2023  润新知