全排列--带去重(DFS,深入理解递归思想)

【问题描述】
给定n个数(可重复)
要求输出没有重复的全排列结果

【输入】
3
1 2 2

【输出】
1 2 2
2 1 2
2 2 1

【思路】
突然在网上看到一个全排列带去重的题,居然把我问懵到了,不知道如何去重。。。后来查了点资料后豁然开朗,维护一个last变量,将上一次尝试过的值记录下来,如果下次尝试与last的值一样,那么就没有必要尝试!

这里要很好的理解递归的话,其实这个问题就很简单了。我们定义dfs(1)是将1–n个数进行全排列,那么我们只需要考虑第一位有几种选择就ok了,因为后面n - 1位的全排列就是dfs(2)的结果!

代码:

/*
给定n个数(可重复)
要求输出没有重复的全排列结果 
*/
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn = 100;
int n;
int a[maxn];
int x[maxn];
int tag[maxn];

bool jianzhi(int i, int last)
{
	if(tag[i] == 1)
		return false;
	if(last == a[i])		//不能和上次放的数一样大 
		return false;
	return true;
}

void dfs(int k)
{
	if(k > n)
	{
		for(int i = 1;i <= n;i++)
		{
			cout << x[i] << " ";
		}
		cout << endl;
		return ;
	}
	//由于要去重,每个位置相同的数只能放一次 
	int last = -1;				//维护一个变量last,用来存本位上一个放过的值 
	for(int i = 1;i <= n;i++)
	{
		if(jianzhi(i, last))
		{
			tag[i] = 1;
			x[k] = a[i];
			last = a[i];		//last值就改掉 
			dfs(k + 1);
			tag[i] = 0;
		}
	}
}

int main()
{
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
		cin >> a[i];
	}
	sort(a + 1, a + 1 + n);				//这个排序为后面去重做好准备 
	dfs(1);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40163242/article/details/88121213