「首先排列是有序的,也就是说[1,2] 和[2,1] 是两个集合,这和之前分析的子集以及组合所不同的地方」。
可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。
但排列问题需要一个used数组,标记已经选择的元素,如图橘黄色部分所示
可以看出叶子节点,就是收割结果的地方。
那么什么时候,算是到达叶子节点呢?
当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列,也表示到达了叶子节点。
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(vector<int>& nums,vector<bool>& used){
if(path.size()==nums.size()){
res.push_back(path);
return;
}
for(int ii=0;ii<nums.size();ii++){
if(used[ii]==true) continue;// path里已经收录的元素,直接跳过
used[ii]=true;
path.push_back(nums[ii]);
backtracking(nums,used);
path.pop_back();
used[ii]=false;
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(),false);
backtracking(nums,used);
return res;
}
};
排列问题:
每层都是从0开始搜索而不是startIndex
需要used数组记录path里都放了哪些元素了
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(vector<int>& nums,vector<bool>& used){
if(path.size()==nums.size()){
res.push_back(path);
return;
}
for(int ii=0;ii<nums.size();ii++){
if((ii>0&&nums[ii-1]==nums[ii]&&used[ii-1]==false)||(used[ii]==true)) continue;
used[ii]=true;
path.push_back(nums[ii]);
backtracking(nums,used);
path.pop_back();
used[ii]=false;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end());
backtracking(nums,used);
return res;
}
};