——————————————————————————————————————————————————
【递归】
方法1:交换法
(这种方法的结果是对的,但是不是按照字典序输出的,所以不能AC…)
import java.util.Scanner;
public class Main {
static int[] a;
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
a = new int[n + 1];
for(int i = 1;i <= n;i++) a[i] = i;
sc.close();
f(1);
}
private static void f(int k) {
if(k == n + 1) {
for(int i = 1;i <= n;i++) System.out.print(a[i] + " ");
System.out.println();
}
for(int i = k;i <= n;i++) {
int t = a[k];
a[k] = a[i];
a[i] = t;
f(k + 1);
t = a[k];
a[k] = a[i];
a[i] = t;
}
}
}
方法2:递归
依次枚举每个位置放哪个数
字典序最小:只需要注意从小到大枚举即可
(本题有个坑-- “每个数字保留5个场宽”,意思就是数字前面加四个空格…)
import java.util.Scanner;
public class Main {
static int[] state;//state[k]:0表示 k 位置上还没放数,i(1--n) 表示 k 位置上放了 i
static int n;
static boolean[] used;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
state = new int[n + 1];
used = new boolean[n + 1];
dfs(1);
sc.close();
}
//k范围:1--n
private static void dfs(int k) {//确定到第 k 个位置
if(k > n) {//确定完一种方案
//输出该方案
for(int i = 1;i <= n;i++) {//遍历每个位置
System.out.print(" " + state[i]);
}
System.out.println();
return ;
}
for(int i = 1;i <= n;i++) {//决定 k 位置上放哪个数
if(!used[i]) {
state[k] = i;//k位置上放 i
used[i] = true;
dfs(k + 1);
//恢复现场
state[k] = 0;
used[i] = false;
}
}
}
}