题目
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
算法描述
解决一个回溯问题,实际上就是一个决策树的遍历过程。一般来说,我们需要解决三个问题:
路径:也就是已经做出的选择。
选择列表:也就是你当前可以做的选择。
结束条件:也就是到达决策树底层,无法再做选择的条件。
我们所使用的框架基本就是:
LinkedList result = new LinkedList();
public void backtrack(路径,选择列表){
if(满足结束条件){
result.add(结果);
}
for(选择:选择列表){
做出选择;
backtrack(路径,选择列表);
撤销选择;
}
}
其中最关键的点就是:在递归之前做选择,在递归之后撤销选择。
方法一
class Solution {
private:
vector<vector<int>>ans;
int n;
public:
vector<vector<int>> permute(vector<int>& nums) {
n=nums.size();
permutation(0,nums);
return ans;
}
void permutation(int start,vector<int>& nums){
if(start==n-1)
{
ans.push_back(nums);
return ;
}
for(int i=start;i<n;i++){
swap(nums[i],nums[start]);
permutation(start+1,nums);
swap(nums[i],nums[start]);
}
}
};
方法二
class Solution {
private:
vector<vector<int>>ans;
vector<int> curr;
int used[10000];
int n;
public:
vector<vector<int>> permute(vector<int>& nums) {
n=nums.size();
for(int i=0;i<n;i++)
used[i]=0;
sort(nums.begin(),nums.end());
permutation(nums);
return ans;
}
void permutation(vector<int>& nums){
if(curr.size()==nums.size()){
ans.push_back(curr);
return;
}
for(int i=0;i<n;i++){
if(used[i]){
continue;
}
curr.push_back(nums[i]);
used[i]=1;
permutation(nums);
curr.pop_back();
used[i]=0;
}
}
};
举一反三
题目描述
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
算法描述
由于本题需要返回所有不重复的全排列,有限制条件,所以需要进行剪枝。这里第一步先要给数组进行排序。
首先,先要给nums进行排序,这样的做目的是方便剪枝
其次,我们已经选择过的不需要再放进去了
接下来,如果当前节点与他的前一个节点一样,并其他的前一个节点已经被遍历过了,那我们也就不需要了。
代码
class Solution {
private:
vector<vector<int>>ans;
vector<int> curr;
int used[10000];
int n;
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
n=nums.size();
for(int i=0;i<n;i++)
used[i]=0;
sort(nums.begin(),nums.end());
permutation(nums);
return ans;
}
void permutation(vector<int>& nums){
if(curr.size()==nums.size()){
ans.push_back(curr);
return;
}
for(int i=0;i<n;i++){
if(used[i]){
continue;
}
if(i>0&&nums[i]==nums[i-1]&&used[i-1])
continue;
curr.push_back(nums[i]);
used[i]=1;
permutation(nums);
curr.pop_back();
used[i]=0;
}
}
};