回溯算法
简单一个例子:给定给定数字n,从中找到和为m的组合,1到n的数字每次使用一次
例 :输入:5 6
输出:1 2 3
1 5
2 4
这里需要注意:
1、在将其结果得到的list加到ArrayList,这里使用res.add(new ArrayList<>(list));
是对list拷贝后放进去,如果直接add,则会使得在后面remove将元素都移除掉;
2、回溯回去list.remove(list.size() - 1); 这里回退回去,是一直变动的,从没有到有到没有;
3、展示的时候注意对空格的把握
package huisu;
/*
* 给定数字n,从中找到和为m的组合
* 采用回溯法
* */
import java.util.ArrayList;
import java.util.Scanner;
public class Sum {
static ArrayList<ArrayList<Integer>> res =new ArrayList<ArrayList<Integer>>();
static ArrayList<Integer> list = new ArrayList<>();
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
dfs(1,m,n);
//这里将拿到的结果进行遍历展示
for(ArrayList<Integer> list : res) {
int i = 0;
//因为这里后面需要读到i的值,这里把i的初始化放在外面,和后面的System.out.println(list.get(i));同一个作用域
for(; i < list.size() - 1; i++) {
//注意这里list.size(),而不是length
System.out.print(list.get(i) + " ");
}
System.out.println(list.get(i));
}
}
//关键代码,实现遍历
public static void dfs(int index, int count, int n) {
if(count==0) {
/*这一步将其结果得到的list加到ArrayList,这里使用
*res.add(new ArrayList<>(list));
*是对list拷贝后放进去,如果直接add,则会使得在后面remove将元素都移除掉*/
res.add(new ArrayList<>(list));
}else {
for(int i = index; i <= count && i <= n; i++) {
list.add(i);
dfs(i + 1, count - i, n);
list.remove(list.size() - 1);
//这里回退回去,是一直变动的,从没有到有到没有
}
}
}
}