花样全排列(leetcode46,leetcode47)
作者:互联网
普通全排列
普通方法
dfs+bool数组判断是否访问过
花样方法
dfs + 交换头元素
http://xiaohuiliucuriosity.blogspot.com/2014/12/permutations.html
permutation of A[1…n] equals to
A[1] + permutation of (A[1…n] - A[1])
A[2] + permutation of (A[1…n] - A[2])
…
A[n] + permutation of (A[1…n] - A[n]).
通过交换的方法来修改第一个数值
swap(num[begin], num[i]);
去重全排列
有重复元素,全排列的结果不能重复
我的思路
很简单的思路。在全排列的基础上,对每一层进行判断,该层相同的元素只能被往下递归一次。
编程采用了map判断该元素是否重复出现
正常人的思路
类似于数学上的C排列和A排列,强行为重复的元素设定取值的优先顺序。
排序后,只有排在前面的值用了,排在后面的值才能用。
以1 1 2 为例
第一个结果 1 1 2
第二个结果 1 2 1
第三个结果 2 1 1(不能是1 1 2因为第二个1不能排在第一个1前面。也不会有第四个结果)
核心代码:排序+ //下一个重复值只有在前一个重复值被使用的情况下才可以使用
if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;
大佬的思路
保证每次取出的头元素都是不重复的。
注意递归时使用的是vector< int > num,不带&也就是每次回到当前层,num值都是上一层的值,即后面递归的操作不对当前层产生影响
并且顺序变化后不变回来
核心代码:排序+ if(i != begin &&num[begin] == num[i])continue;
eg:
1 1 2 2 3
2 1 1 2 3(头元素已经变成2了,头元素只2一次)
3 1 1 2 1
代码
去重全排列之我的代码
class Solution {
public:
vector<vector<int>> ans;
vector<int>index;
vector<map<int,int>>exists;
map<int,int>mapp;
void dfs(int deep,vector<int>&per, vector<int> &nums)
{
int n = nums.size();
if (deep == n)
{
ans.push_back(per);
return;
}
for(int i = 0; i < n; i ++)
{
if(!index[i] &&!exists[deep][nums[i]]){
exists[deep][nums[i]] ++;
index[i] = 1;
per.push_back(nums[i]);
dfs(deep + 1,per,nums);
per.pop_back();
// exists[deep][nums[i]]--;
index[i] = 0;
}
}
exists[deep].clear();
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<int> per;
mapp.clear();
int n = nums.size();
for(int i = 0; i < n; i ++)
{
index.push_back(0);
exists.push_back(mapp);
}
dfs(0,per,nums);
return ans;
}
};
去重全排列大佬的代码
class Solution {
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
vector<vector<int> > result;
sort(num.begin(),num.end());
permuteRecursive(num, 0, result);
return result;
}
// permute num[begin..end]
// invariant: num[0..begin-1] have been fixed/permuted
void permuteRecursive(vector<int> num, int begin, vector<vector<int> > &result) {
if (begin == num.size() - 1) {
// one permutation instance
result.push_back(num);
return;
}
for (int i = begin; i < num.size(); i++) {
if(i != begin &&num[begin] == num[i])continue;
swap(num[begin], num[i]);
permuteRecursive(num, begin + 1, result);
// reset
//swap(num[begin], num[i]);
}
}
};
标签:begin,num,花样,nums,int,per,vector,leetcode47,leetcode46 来源: https://blog.csdn.net/weixin_44147606/article/details/87989766