常规DFS思路:
void P(vector<vector<int>> &result,vector<int> &nums,vector<int> &now,vector<bool> &flag,int index)
{
if(index==nums.size())
result.push_back(now);
else
{
for(int i=0;i<nums.size();i++)
{
if(flag[i]==false)
{
now.push_back(nums[i]);
flag[i]=true;//用来记录是否被使用过
P(result,nums,now,flag,index+1);
now.pop_back();
flag[i]=false;
}
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> flag(nums.size(),false);//vector初始化
vector<int> now;
vector<vector<int>> result;
P(result,nums,now,flag,0);
return result;
}
除此之外,看到一种基于交换的方法,看着更加简洁,但是略微影响了输出的顺序(不是按字典序输出了)
void permuteRecursive(vector<int> &num, int begin, vector<vector<int> > &result) { if (begin==num.size()-1) {//此处不用到num.size(),因为最后一次必然是自我交换,可以提前结束 result.push_back(num);
return;
} for (int i = begin; i < num.size(); i++) { swap(num[begin], num[i]); permuteRecursive(num, begin + 1, result); swap(num[begin], num[i]);//回溯,但若传入的是num,不是&num,则无需回溯,因为是局部变量,但效率会更低 } } vector<vector<int> > permute(vector<int> &num) { vector<vector<int> > result; permuteRecursive(num, 0, result); return result; }
下面是存在重复数字的解法:
void recursion(vector<int> num, int i, int j, vector<vector<int> > &res) { if (i == j-1) { res.push_back(num); return; } for (int k = i; k < j; k++) { if (i != k && num[i] == num[k]) continue;//多了一行重复判断 swap(num[i], num[k]); recursion(num, i+1, j, res);//此处不能回溯
} } vector<vector<int> > permuteUnique(vector<int> &num) { sort(num.begin(), num.end()); vector<vector<int> >res; recursion(num, 0, num.size(), res); return res; }
本以为传入&num并回溯和传入num不回溯是没有区别的,但是此处回溯就回出错,两者其实是有略微区别的,若回溯,那么数组在第二个swap语句结束时,直接还原,若不回溯,则数组会在整个for循环结束后再还原。此处很抽象,也难以理解如何保证不重复的,下面有回溯的解法:
void permuteRecursive(vector<int> &num, int begin, vector<vector<int> > &result) {
if (begin >= num.size()) {
result.push_back(num);
return;
}
for (int i = begin; i < num.size(); i++) {
int flag=false;
for(int j=begin;j<i;j++) //特意为了排除1122中二号位与4号位交换成1221这种情况,这种相同数字的相对位置发生改变的情况必然会导致接下来的重复
if(num[j]==num[i])
{flag=true;break;}
if(i==begin||flag==false)
{
swap(num[begin], num[i]);
permuteRecursive(num, begin + 1, result);
swap(num[begin], num[i]);
}
}
}
vector<vector<int>> permuteUnique(vector<int> &num) {
vector<vector<int> > result;
sort(num.begin(),num.end());
permuteRecursive(num, 0, result);
return result;
}