【问题描述】
给定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;
}