此前,也写过一篇用dfs解决全排列问题的博客,今天又遇到一个变形,于是忍不住就撸了一把代码。
题目描述:
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ]
这跟之前的思路类似,还是以每一个数为根深度优先搜索其他的数,每条路径即是一条解法,但是也有差别,之前不重复的序列,现在是包含重复数字的序列,若要返回不重复的全排列这里需要做一些简单的修改。以上诉示例明--a[0] = 1, a[1] = 1, a[2] = 2,那么组成的排列按着之前的思路解法有以a[0]为根有:a[0]->a[1]->a[2] a[0]->a[2]->a[1], 以a[1]为根有a[1]->a[0]->a[2],a[1]->a[2]->a[1]这里是不是以a[0,a[1]为根搜索出来的排列是重复的,因为a[0] == a[1],其他的数字不变,以他们为根刚刚好可以组成重复的两套排列,那么思路就有了:
1) 把输入数列排序
2)遍历各个数组为根的时候,如果有前一个数,且跟相等,且前一个数已经作为根搜索过,那么跳过这个数。
献上代码:
void DFS(int k, vector<int>&nums, vector<int>&pa, vector<vector<int>>&res, bool fa[])
{
if (k == nums.size()) {
res.push_back(pa);
return;
}
for (int i = 0; i < nums.size(); i++) {
if (i > 0 && nums[i] == nums[i-1] && fa[i-1] == true) {//修改的地方
continue;
}
if (fa[i] == 0) {
pa.push_back(nums[i]);
fa[i] = 1;
DFS(k+1, nums, pa, res, fa);
fa[i] = 0;
pa.pop_back();
}
}
}
vector<vector<int>> permute(vector<int>& nums)
{
vector<vector<int>>a;
vector<int>ans;
bool flag[50];
for (int i = 0; i < 50; i++) {
flag[i] = false;
}
vector<int>num_temp;
num_temp = nums;
sort(num_temp.begin(), num_temp.end());
DFS(0, num_temp, ans, a, flag);
return a;
}