题目出处点这里
有两种方法,但本质都是深度优先搜索deep first search
第一种(讲解见代码):
package violence;
import java.util.Scanner;
public class P1706_1 {
static int n;
static boolean[] isUsed = new boolean[10];//用来判断相应数字有没有被使用过
static int[] res = new int[10]; //用来存储结果
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dfs(0);
}
public static void dfs(int now) {//now代表现在res数组里有几个数字,也可以理解为当前索引
if (now == n ) {//当now == n 时,就说明已经满了,直接输出即可
print();
return;
}
for (int i = 0; i < n; i++) {
if (!isUsed[i]) {//判断是否被用过
isUsed[i] = true;//既然进来了,就设为使用过了
res[now] = i + 1;//因为n是1-9,所有i+1
dfs(now+1);//加入后now+1
//最后回溯是对isUsed[i]回溯;如果写成isUsed[now]的话
//由于每次回溯时now==n,所以写成isUsed[now]的话其实每次就只把最后一个数置为false
isUsed[i] = false;//回溯
}
}
}
//输出
public static void print() {
for (int i = 0; i < n; i++) {
System.out.print(" "+res[i]);
}
System.out.println();
}
}
第二种(讲解见代码):
为方便输出用ArrayList代替了stack
package violence;
import java.util.ArrayList;
import java.util.Scanner;
public class P1706_2 {
static int n;
static ArrayList<Integer> list = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int arr[] = new int[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
dfs(0);
}
/**
*
* @param has 代表目前list里有多少个数
*/
public static void dfs(int has) {//has代表list有多少个数
if (has == n) {//满了就输出
print();
return;
}
for (int i = 0; i < n; i++) {
if (!list.contains(i+1)) {//避免数字重复
list.add(i+1);//直接加入数组
dfs(has+1);//进行下一次递归,has+1
list.remove(list.size() - 1);//把队尾数字去掉
}
}
}
//输出
public static void print() {
for (int i = 0; i < n; i++) {
System.out.print(" "+list.get(i));
}
System.out.println();
}
}