全排列1
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
n = nums.size();
vector<bool> visit(n,false);
dfs(nums,visit);
return res;
}
private:
vector<vector<int>> res;
vector<int> path;
int n;
void dfs(vector<int>& nums,vector<bool>& visit){
//返回的边界条件
if(path.size() == nums.size()){
res.push_back(path);
return;
}
for(int i=0;i<n;i++){
if(visit[i]) continue; //判断是否已经访问过
//添加nums[i]进入路径
path.push_back(nums[i]);
visit[i] = true;
//深度搜索
dfs(nums,visit);
//退出路径
path.pop_back();
visit[i] = false;
}
}
};
全排列2
给定一个可包含重复数字的序列,返回所有不重复的全排列。
本题全排列要除重的是:在同一个递归循环中,不能在同一位置多次选择相同的数字!
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
n = nums.size();
vector<bool> visit(n,false);
sort(nums.begin(),nums.end()); //进行排列之后,重复数字就连续在一起了
dfs(nums,visit);
return res;
}
private:
vector<vector<int>> res;
vector<int> path;
int n;
void dfs(vector<int>& nums,vector<bool>& visit){
//返回的边界条件
if(path.size() == nums.size()){
res.push_back(path);
return;
}
for(int i=0;i<n;i++){
if(i!=0 && nums[i] == nums[i-1] && !visit[i]) continue; //去重
if(visit[i]) continue; //判断是否已经访问过
//添加nums[i]进入路径
path.push_back(nums[i]);
visit[i] = true;
//深度搜索
dfs(nums,visit);
//退出路径
path.pop_back();
visit[i] = false;
}
}
};
map去重与重新构造nums
class Solution {
public:
vector<vector<int>> ans;
vector<vector<int>> permuteUnique(vector<int>& nums) {
dfs(nums, 0);
return ans;
}
void dfs(vector<int> nums, int idx) {
int n = nums.size();
if (idx == n) ans.emplace_back(nums); //emplace_back--在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。
unordered_set<int> s;
for (int i = idx; i < n; ++i) {
if (s.find(nums[i]) != s.end()) continue; //剪枝
s.insert(nums[i]);
vector<int> tmp = nums;
swap(tmp[idx], tmp[i]);
dfs(tmp, idx + 1);
}
}
};