博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
力扣22. 括号生成
阅读量:3915 次
发布时间:2019-05-23

本文共 3631 字,大约阅读时间需要 12 分钟。

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

示例:

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

思路:dfs 回溯

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

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

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

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

做加法:

1 class Solution { 2     public List
generateParenthesis(int n) { 3 // dfs回溯 4 List
res = new ArrayList
(); 5 if(n == 0) 6 return res; 7 dfs(res, 0, 0,n, ""); 8 return res; 9 }10 11 public void dfs(List
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
generateParenthesis(int n) { 3 // dfs回溯 4 5 List
res = new ArrayList
(); 6 if(n == 0) 7 return res; 8 dfs(res, n, n,n, ""); 9 return res;10 }11 12 public void dfs(List
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
generateParenthesis(int n) { 3 // dfs回溯 4 5 List
res = new ArrayList
(); 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
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 }

思路来源:

转载地址:http://uidrn.baihongyu.com/

你可能感兴趣的文章
【招聘(深圳)】轻岁 诚聘.NET Core开发
查看>>
await,async 我要把它翻个底朝天,这回你总该明白了吧
查看>>
.NET Core实用技巧(一)如何将EF Core生成的SQL语句显示在控制台中
查看>>
使用Jenkins来发布和代理.NetCore项目
查看>>
欢迎来到 C# 9.0(Welcome to C# 9.0)
查看>>
Dapr微服务应用开发系列1:环境配置
查看>>
使用 Visual Studio 2019 批量添加代码文件头
查看>>
【BCVP更新】StackExchange.Redis 的异步开发方式
查看>>
Istio 1.7——进击的追风少年
查看>>
.NET5.0 Preview 8 开箱教程
查看>>
efcore技巧贴-也许有你不知道的使用技巧
查看>>
真・WPF 按钮拖动和调整大小
查看>>
做权限认证,还不了解IdentityServer4?不二话,赶紧拥抱吧,.NET Core官方推荐!...
查看>>
MongoDB最新4.2.7版本三分片集群修改IP实操演练
查看>>
编写第一个 .NET 微服务
查看>>
深入探究.Net Core Configuration读取配置的优先级
查看>>
Blazor带我重玩前端(六)
查看>>
使用 C# 捕获进程输出
查看>>
数据库单表千万行 LIKE 搜索优化手记
查看>>
.NET Core 中生成验证码
查看>>