[1] 数字全排列问题

题意:顾名思义,就是输入若干次数字,将1到该数字的全排列输出

算法:DFS

问题:第一次接触DFS算法问题,并不容易理解其中递归的写法(特别是回溯的理解)。具体问题可见代码注释部分。(有一次写了dfs(++step)就错了,因为每层之内的step不能轻易改变,后面回溯回来也是需要查看step值的,只能用step+1)

思路:每选择一个数后,将该数标记,将未标记过的的数看作一个小的全排列问题,依次转化,转化n-1次后结束,输出该次排列。再将最后一次小的全排列问题用到的数字的标记取消,就可以退回到第n-2次转化后的结果,再往下进行新的全排列,每层结束都会回溯到上一层。(难点:vis[i]=0就是这个作用,通过让标记取消回溯)

代码:ac

#include<bits/stdc++.h>
using namespace std;
int n;
int num[10], vis[10];/*前者存放选中的数,后者存放该数字是否选中的标记*/
void dfs(int step);
int main()
{
	while (scanf("%d", &n) == 1)
	{
		memset(vis, 0, sizeof(vis));
		dfs(1);
	}
	return 0;
}
void dfs(int step)
{
	if (step == n + 1)/*先写出口*/
	{
		for (int i = 1; i <= n; i++)
		{
			printf("%d ", num[i]);/*输出该次排列选中的数*/
		}
		printf("\n");
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (vis[i] == 0)
		{
			num[step] = i;/*存放排列选中的数字*/
			vis[i] = 1;/*标记该数字已选过*/
			dfs(step + 1);/*进行该排列的下一步,选择下一个未选过的数字*/
			vis[i] = 0;/*如果不写这个,一次排列就结束了,无法回溯;写了以后,可以回到上一层的下一个i + 1继续排列*/
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值