DFS-带重复元素的全排列

来源:互联网 发布:vb控件适应窗体大小 编辑:程序博客网 时间:2024/05/22 10:46

此题是全排列问题的变形,给出的列表中有重复数字,需要去重。解决全排列问题的思路参见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;即去除了访问后面元素时,前一个元素还没有被访问的情况,完成了去重的任务

原创粉丝点击