题目
括号生成
公众号 《java编程手记》记录JAVA学习日常,分享学习路上点点滴滴,从入门到放弃,欢迎关注
描述
难度:中等
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
提示:
1 <= n <= 8
题意解析
更好的理解题意非常有助于解题,所以加入了题意解析环节
这道题本质上是通过输入的数字N
,生成N
对()
,并且左括号
,右括号
可打乱排列,但是必须有效,即必须要一一
对应,不可以出现)))(((
类似这样的例子
那么这道题的第一个思路就出来了,暴力解法,我们只需要按照N
的值去生成所有可能生成的括号即可,然后通过出栈入栈
操作来筛选符合有效
这个规则的结果即可,暴力解法的结果就是时间复杂度很高,生成的括号数为2N
(左右括号两个),需要生成2^2N
个结果值,对于每个结果最多可能需要N
层遍历才可知道结果值是否有效,最终时间复杂度为O(2^2N*N)
由于暴力解法实在累人,就没有去写,直接进入正题,回溯法,简单介绍下回溯法 把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解
,说白了就是将思路转换为树的数据结构,然后进行搜索,找到最优解的一种解法,针对这道题,我在leetCode
的解法中找到了一张十分形象的图,能够很生动的描述,树状,遍历等行为,废话不多说直接上图
Solution
回溯解法
解题思路
整体解题思路
- 设定两个变量
left
,right
用来表示可添加的左括号数
和可添加的右括号数
, - 当添加一个
左括号
后,可添加左括号数量减一,即left--
,同时当新增一个左括号后,对应需要有一个右括号,即右括号数加一,right++
, - 当添加一个
右括号
后,可添加左括号数量不变,可添加右括号数减一,right--
, - 当
left>0
时,可以选择继续添加左括号,同时left--
,right++
- 当
right>0
时,可以选择继续添加右括号,同时right--
,left不变 - 当
left
和right
都为0
时,即没有可添加的左括号和右括号,扔入结果返回
CODE
class Solution {
//结果list
List<String> list = new ArrayList();
public List<String> generateParenthesis(int n) {
//初始left为n,right为0,字符串为空串
backtrace("",n,0);
return list;
}
public void backtrace(String str,int left , int right){
//left和right都为0时,组装结果,返回
if(left==0 && right==0){
list.add(str);
return ;
}
//有可用的左括号时,添加左括号,继续递归,同时left-1,right+1
if(left > 0){
backtrace(str+"(",left-1,right+1);
}
//有可用的右括号时,添加左括号,继续递归,同时left不变,right-1
if(right > 0){
backtrace(str+")",left,right-1);
}
}
}
复杂度
- 算不出来哈哈
结果
- 执行用时:
1
ms, 在所有Java
提交中击败了96.69
%的用户 - 内存消耗:
38.7
MB, 在所有Java
提交中击败了43.76
%的用户
LeetCode名句
woshishabi