[AcWing]842. 全排列数字

给定一个整数 n,将数字 1 ~ n 排成一排,将会有很多种排列方法。

现在,请你按照字典序将所有的排列方法输出。

输入格式

共一行,包含一个整数 n

输出格式

按字典序输出所有排列方案,每个方案占一行。

数据范围

1 \le n \le 7

输入样例:

1
3

输出样例:

1
2
3
4
5
6
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

算法思想

此题,适合用来理解DFSDFS可以用模型来理解。

image-20240419202755100

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

using namespace std;

const int N = 10;

int n; // 多少位数字
int path[N]; // 装数字
bool st[N]; // 在DFS的过程中,数字是否已经被用过了

// 参数:当前递归是确定第 u 位(从左往右看)
void dfs(int u){
// 从图看出来的。
// 第一层确定第 1 位数字,第n层确定第 n 层的数字。
if(u == n){
// 确定完毕,输出
for(int i = 0; i < n; i++){
cout << path[i] << " ";
}
cout << endl;
return;
}

// u < n 的情况,在递归中
for(int i = 1; i <= n; i++){
// 这个数字,没有被用过
if(!st[i]){
// 用一下,这个数字已经用过了,并且放入path里面展示
st[i] = true;
path[u] = i;
// 递归下一位
dfs(u + 1);
// 回溯的时候,恢复现场
// 因为有数字回退,回溯完,下一次递归需要使用新的path和st。
// path[i] = 0; 可以写,也可以不写,严格来说要写。
st[i] = false;
}
}
}

int main(){
// 全排列数字n
cin >> n;

// 从第 0 位开始(从左往右)
dfs(0);

return 0;
}