回溯总结
组合 | 子集 | 全排列 |
---|
无序 | 无序 | 有序 |
for(i = start) | for(i = start) | for(i = 0) |
在叶子处 push_back | 入口即push_back | 在叶子处 push_back |
if(i>start && num[i] == num[i-1]) | – | visited数组 |
46. 全排列
- 要求顺序 for 循环从0开始
- 可以使用map来记录已经visited的节点或者是从path数组进行判断
class Solution {
public:
vector<vector<int>>result;
vector<int>path;
vector<vector<int>> permute(vector<int>& nums) {
dfs(nums);
return result;
}
void dfs(vector<int>& nums){
if(path.size() >= nums.size()){
result.push_back(path);
return;
}
for(int i=0; i<nums.size(); i++){
if(find(path.begin(), path.end(), nums[i]) == path.end()){
path.push_back(nums[i]);
dfs(nums);
path.pop_back();
}
}
}
};
47. 全排列 II
- 有序
- 包含重复数字---->同一树层进行去重
- if(i>0 && nums[i] == nums[i-1] && !mp[i-1]) continue;
含义: 在该层的选择中, 当前节点跟前一个相同,但是前一个结点还没有用过。这一定是重复的。
class Solution {
public:
vector<vector<int>>result;
vector<int>path;
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<bool>mp(nums.size(), false);
dfs(nums, mp);
return result;
}
void dfs(vector<int>& nums,vector<bool>&mp){
if(path.size() >= nums.size()){
result.push_back(path);
return;
}
for(int i=0; i<nums.size(); i++){
if(mp[i]) continue;
if(i>0 && nums[i] == nums[i-1] && !mp[i-1]) continue;
path.push_back(nums[i]);
mp[i] = true;
dfs(nums, mp);
mp[i] = false;
path.pop_back();
}
}
};