1. 问题描述: 题目网址为:https://leetcode-cn.com/problems/generate-parentheses/,
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
2. 思路分析:
① 题目不难理解,可以使用递归来求解,核心是怎么样判断添加的括号是合法的,我们可以从左边依次添加括号,可以发现当左括号的数量大于等于右括号的时候我们可以在原来的基础上添加左括号,比如之前的括号状态为()(),那么我们在下一步添加括号的时候就可以添加左括号,这个时候是合法的,当左括号的数量大于右括号的时候那么可以添加右括号,比如()(这种情况是可以添加右括号的,当左括号等于右括号的数量的时候是不可以添加右括号的,比如()()这个时候左右括号的数量都等于了2
② 从①中分析可知,在当前的括号序列中存在两种合法的添加左右括号的操作,对应着两种平行状态,分别为可以添加左括号与右括号,基于这个我们可以使用两个变量left,right来记录中间递归的结果,为当前得到的括号序列中左右括号的数量,当可以添加括号的时候执行下一步的递归操作
③ 递归满足的出口是当左右括号的数量都等于n的时候,因为这个时候括号匹配完毕,向List结果集中添加匹配的字符串序列,此外假如判断出左括号或者是右括号的数量大于了给定的数字n那么也return,因为在递归的时候可能一直添加左括号,所以需要return,因为这个时候添加的括号序列是不合法的,没有return会一直递归下去
在写代码的过程最好结合测试用例和自己简单举出一些例子把细节处理好,整个递归的过程还是比较好理解的,代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Solution {
List<String> res = new ArrayList<>();
public List<String> generateParenthesis(int n) {
/*第二个参数是当前记录的左括号的数量, 第三个参数是记录的右括号的数量, 第四个参数是当前生成括号结果在添加括号的时候
* 判断当前是否左括号的数量大于等于右括号的数量这样就可以进行判断是否可以添加括号
* 根据上面的分析可以知道存在两个平行状态, 一个是可以添加左括号, 另外一个是可以添加右括号
* 两个状态是不受影响的, 所以不能够使用if-else而是if来判断, 递归的出口是左括号与右括号的
* 数量等于了目标的括号的时候, 其实思路还是比较好理解的
* */
recursion(n ,0 ,0, "");
return res;
}
/*递归左括号与右括号*/
private void recursion(int n, int left, int right, String cur) {
if (left == n && right == n){
res.add(cur);
return;
}
if (left > n || right > n) return;
/*if判断之后才决定下一步是否可以递归下去
* 并且只有当左括号的数量大于等于了右括号的数量才可以添加左括号, 左括号的数量大于了右括号
* 才可以添加右括号
* */
if (left >= right){
recursion(n, left + 1, right, cur + "(");
}
if (left > right){
recursion(n, left, right + 1, cur + ")");
}
}
}