给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
共一行,包含一个整数 n。
按字典序输出所有排列方案,每个方案占一行。
1≤n≤7
3
- 1 2 3
- 1 3 2
- 2 1 3
- 2 3 1
- 3 1 2
- 3 2 1
思路:
DFS算法每次都往深搜,到达叶子结点后回溯
这道题使用DFS即可做出,因为结合了递归不好理解,先将递归解释:递归就是函数调用自身,遇到终止条件后返回。
借用这篇文章的程序:[AcWing]842. 排列数字(C++实现)dfs模板题,递归思想的解释_Cloudeeeee的博客-CSDN博客
- #include
- using namespace std;
-
- int n;
-
- void func(int u){
- if(u == 0) return;
- cout << "Recursive program goes to the next level --- " << u << endl;
- func(u-1);
- cout << "Recursive program backtracking --- " << u <
- return;
- }
- int main(){
- cin >> n;
- func(n);
- return 0;
- }
得到结果:
我们可以得到这样的流程 :

由此我们就理解了递归的流程,下面是DFS对这道题的解法:一个位置一个位置的填入数字,如果没有空位置了就让最后一个填的数字可用并返回

示例代码:
- #include
- using namespace std;
- const int N=10;
- int path[N]; //记录位置信息
- bool st[N]; //保存这个位置用过了没有,用过就设为true,默认初始为false
- int n;
- void dfs(int u) //u表示当前填的位置
- {
- if( u == n ) //所有位置都填满了(u现在变成了最后一个位置的下一位),此时输出
- {
- for(int i=0;i
" "; - cout<
- return;
- }
- for(int i=1;i<=n;i++) //枚举当前位置还可以填哪些数
- {
- if(!st[i]) //如果这个数字还能用
- {
- path[u] = i; //把数字填到当前位置上,i表示从1到n的数字
- st[i] = true; //记录当前数字已经被使用
- dfs(u+1); //填下一个位置
- st[i] = false; //回溯的时候要恢复,这个数字现在可以用
- } //注意:回溯不仅是return,还有for循环
- }
-
- }
- int main()
- {
-
- cin>>n;
- dfs(0); //从第0个位置开始看
- return 0;
- }
注意:这个程序里面回溯不仅仅是递归终止的return,还有for循环,比如运行到st[i] = false;的时候整个if语句就结束了,但是可能上面的for循环还没有结束,要再次进行循环操作
- for(int i=1;i<=n;i++) //枚举当前位置还可以填哪些数
- {
- if(!st[i]) //如果这个数字还能用
- {
- path[u] = i; //把数字填到当前位置上,i表示从1到n的数字
- st[i] = true; //记录当前数字已经被使用
- dfs(u+1); //填下一个位置
- st[i] = false; //回溯的时候要恢复,这个数字现在可以用
- } //注意:回溯不仅是return,还有for循环
- }
这道题光看代码可能不太好理解,所以我把程序运行的流程图画了出来,例如输入3的时候 ,下面的三张图分别代表着dfs(0)情况下,i=1,i=2,i=3的运行流程



大家不理解的话也可以在纸上自己写一遍
-
相关阅读:
边缘计算多角色智能计量插座:用电监测和资产管理的未来智能化引擎
ElasticSearch在Java中的基本使用方式
电脑入门:路由器访问控制列表基础知识
Spring-Cloud GateWay+Vue 跨域方案汇总
超详细的springBoot学习笔记
【数据结构】算法效率的度量方法
活体检测论文 Face Anti-Spoofing with Human Material Perception 阅读笔记
控制三盏灯
使用 AWS S3 SDK 访问 COS-腾讯云国际站代充
LeetCode讲解篇之138. 随机链表的复制
-
原文地址:https://blog.csdn.net/weixin_63504072/article/details/134501290