递归: 自己调用自己,写递归函数前要先写递归的出口(递归结束条件)
回溯: 回溯算法是一种算法思想,而递归则是具体的代码结构。
每完成一趟就一步步回溯到n-1步那里 (通过出栈(把栈内的当前运行函数地址弹出))
函数调用: 将当前运行函数地址入栈,参数入栈等等....具体看汇编
题目:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[ "((()))",
"(()())",
"(())()",
"()(())",
"()()()" ]
*原则: 1. 左括号没用完之前可以随意使用(左括号<n)
2. 右括号数量小于左括号数量之前才可以使用
3. 右括号数等于n时递归结束 (针对单独的各种括号组合)
package myJobTest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
public class Easy_递归回溯括号生成 {
/**
* @param args
*/
public static void main(String[] args) {
int n = new Scanner(System.in).nextInt();
List<String> result = new ArrayList<String>();
result = new Easy_递归回溯括号生成().generateParenthesis(n);
Iterator<String> it = result.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
public List<String> generateParenthesis(int n) {
List<String> list = new ArrayList<String>();
// 开始给helper传入一个空字符串
helper("", n, 0, 0, list);
return list;
}
/**
*
* @param string
* 该字符串用于拼接生成的括号
* @param n
* 代表生成的括号对数
* @param left
* 统计左括号数
* @param right
* 统计右括号数
* @param list
* 由于要返回一个集合,后面将拼接好的字符串加入集合(各种不同的有效括号组合)
*/
// 函数调用: 将当前函数的运行地址入栈。 另外还有参数入栈等等.......
public void helper(String string, int n, int left, int right, List<String> list){
// 递归结束条件 右括号数目用完(等于n) 通过helper函数的right自加累计数目
/**
* 简单的回溯算法,先写n个左括号,然后就写右括号,每当完成一组之后,就把字符串存起来。
* 然后再倒退步骤到写第n-1个左括号,然后写右括号,在写左括号,再全写右括号。
* 依次回溯递归,每完成一趟就回到能再改变的位置。
*/
if (right == n) {
list.add(string);
return; // return之后结束当前方法( 加每一个括号对应的helper方法 ),也就是出栈操作
//接下来就会一步步回溯到第n-1个左括号的位置,()
}
// 回溯算法是一种算法思想,而递归则是具体的代码结构。
// 加左括号
if (left < n) {
helper(string + "(", n, left + 1, right, list);
}
// 加右括号
if (right < left) {
helper(string + ")", n, left, right + 1, list);
}
}
}