DFS-帶重複元素的全排列
阿新 • • 發佈:2018-12-24
此題是全排列問題的變形,給出的列表中有重複數字,需要去重。解決全排列問題的思路參見DFS-全排列問題
去重思路:以[1,2,2]為例,可以要求index=1的數字2在最後生成的排列中一定要在index=2的數字2的前面,強制規定了順序,避免了重複。即先從小到大排序,使相同的數字聚在一起,若前後2個數字相同,訪問後一個數字的時候,前一個數字必須已經訪問過了。只需新增一行程式碼
if(i>0&&nums[i]==nums[i-1]&&!visited[i-1]) continue;
完整的程式碼如下:
class Solution { public: /* * @param : A list of integers * @return: A list of unique permutations */ vector<vector<int>> permuteUnique(vector<int> &nums) { // write your code here //先進行排序 sort(nums.begin(),nums.end()); vector<vector<int>> res; vector<int> tmp; vector<bool> visited(nums.size(),false);//訪問陣列,初始化全為false DFS(res,tmp,visited,nums,0); return res; } void DFS(vector<vector<int>>& res,vector<int>& tmp,vector<bool>& visited,vector<int> &nums,int index){ if(index==nums.size()){//收斂條件 res.push_back(tmp); return; } for(int i=0;i<nums.size();++i){ if(i>0&&nums[i]==nums[i-1]&&!visited[i-1]) continue; if(!visited[i]){//沒有訪問過 visited[i]=true; tmp.push_back(nums[i]); DFS(res,tmp,visited,nums,index+1); visited[i]=false; tmp.pop_back(); } } } };
理解不清楚的話還是畫圖理解的較快,用不同的顏色標記2個相同的數字2,紅色的2要在藍色的2前面(劃紅色斜線表示由於visited陣列作用,避免對同一位置的元素重複使用,為了簡單,只畫了部分)
if(i>0&&nums[i]==nums[i-1]&&!visited[i-1]) continue;即去除了訪問後面元素時,前一個元素還沒有被訪問的情況,完成了去重的任務