C++算法题解 - 递归实现排列型枚举 - 递归法 (图文) (递归搜索树)

题目:递归实现排列型枚举

把 1∼n这n个整数排成一行后随机打乱顺序,输出所有可能的次序。

输入格式
一个整数n。

输出格式
按照从小到大的顺序输出所有方案,每行 1个。
首先,同一行相邻两个数用一个空格隔开。
其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。

数据范围

1≤n≤9

输入样例:
3
输出样例:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

题目链接

题解:

1.方法
方法1: 第一个数放到哪个位置. 例如n==3时, 1放到第一个坑还是第二个坑还是第三个坑.然后再放2...
方法2: 第一个坑放哪个数,第二个坑放哪个数, ...
两种方法实际都一样,仅出发点不同.本题解是方法2.

2.字典序最小
第一个节点开始,先选择最小的,即选择1,之后再次回到第一个节点选择时,
选择最小的,即选择2.而2一定大于1,即符合字典序最小.依次下去,第一个节点的结果一定是符合字典序最小.
递归下去,之后的每个节点一定也符合根节点满足字典序最小的情况.

3.递归搜索树
image

3.时间复杂度分析
image

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
//知道范围后可以开一个很大的全局数组,之后就可以不用传参,方便递归
const int N = 10;
int state[N]; //记录选过的数字
bool used[N]; //false表示未使用过,true表示已使用当前下标的数字
int n; //题目传入参数
void dfs(int u)
{
if(u>n)
{
for(int i = 1; i <= n; i++) //遍历state数组 输出结果
{
printf("%d ",state[i]);
}
puts("");
return ;
}
for(int i = 1; i<=n; i++) //遍历used数组(分支) 寻找未使用过的数字, 并使用该数字
{
if(used[i] == false)
{
used[i] = true;
state[u] = i;
dfs(u+1);
//递归回来后恢复现场
used[i] = false;
state[u] = 0;
}
}
}
int main()
{
scanf("%d",&n);
dfs(1); //从1开始,与层数对应: 1==第一层
return 0;
}
posted @   HJfjfK  阅读(99)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示