本文小编为大家详细介绍“C++回溯算法中的全排列问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++回溯算法中的全排列问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
一、全排列
全排列的特点就是:解放了index(每次遍历都从0开始),但是解放index的同时,又捆绑了used数组,记录已经出现过的元素
class Solution { private: vector<int> path; vector<vector<int>> result; int used[7]={0}; void backtracking(vector<int>& nums){ if(path.size()==nums.size()){ result.push_back(path); return; } for(int i=0;i<nums.size();i++){ if(used[i]==1) continue; path.push_back(nums[i]); used[i]=1; backtracking(nums); used[i]=0; path.pop_back(); } } public: vector<vector<int>> permute(vector<int>& nums) { backtracking(nums); return result; } };
二、全排列II
本题与全排列唯一不同在于需要去重这题与上一题唯一区别在于输入样例为可重复序列,且要求输出样例不重复
对于全排列问题,模板是设置used数组,只有used[i]==0时,才能选择该元素
对于去重问题,模板是先对nums排序,再判断nums[i]与nums[i-1]是否相等
根据全排列问题模板,设置used数组,只有used[i]==0时才可以选择
根据去重模板,先对nums排序,再判断nums[i]与nums[i-1]是否相等
但是全排列的去重没那么简单,因为全排列i是从0开始遍历,因此还要记录同一层当前已经访问到哪儿了,同一层不可以重复,但是同一树枝可以重复
但是不必再设置index,因为used数组可以兼任这个功能
如果used[i-1]==1,说明在同一个树枝访问过nums[i-1],同一树枝可以重复
如果used[i-1]==0,说明在同一层访问过nums[i-1],同一层不可以重复
很绕~
class Solution { private: vector<int> path; vector<vector<int>> result; int used[9]={0}; void backtracking(vector<int>& nums){ if(path.size()==nums.size()){ result.push_back(path); return; } for(int i=0;i<nums.size();i++){ if(i>0&&nums[i]==nums[i-1]&&used[i-1]==0) continue; if(used[i]==0){ path.push_back(nums[i]); used[i]=1; backtracking(nums); used[i]=0; path.pop_back(); } } } public: vector<vector<int>> permuteUnique(vector<int>& nums) { sort(nums.begin(),nums.end()); backtracking(nums); return result; } };