标签:
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[1,1,2]
, [1,2,1]
,
and [2,1,1]
.
这个题跟[LeetCode]46.Permutations非常类似,唯一的区别就是在这个题目中元素集合可以出现重复。这给我们带来一个问题就是如果不对重复元素加以区别,那么类似于{1,1,2}这样的例子我们会有重复结果出现。那么如何避免这种重复呢?方法就是对于重复的元素循环时跳过递归函数的调用,只对第一个未被使用的进行递归,我们那么这一次结果会出现在第一个的递归函数结果中,而后面重复的会被略过。如果第一个重复元素前面的元素还没在当前结果中,那么我们不需要进行递归。想明白了这一点,代码其实很好修改。首先我们要对元素集合排序,从而让重复元素相邻,接下来就是一行代码对于重复元素和前面元素使用情况的判断即可。
/********************************* * 日期:2015-01-19 * 作者:SJF0115 * 题目: 47.Permutations II * 网址:https://oj.leetcode.com/problems/permutations-ii/ * 结果:AC * 来源:LeetCode * 时间复杂度:O(n!) * 空间复杂度:O(n) * 博客: **********************************/ #include <iostream> #include <algorithm> #include <map> #include <vector> using namespace std; class Solution { public: vector<vector<int> > permuteUnique(vector<int> &num) { vector<vector<int> > result; if(num.empty()){ return result; }//if // 排序 sort(num.begin(),num.end()); bool visited[num.size()]; vector<int> visitedVec; // 递归 DFS(num,visited,visitedVec,result); return result; } private: void DFS(vector<int> &num,bool visited[],vector<int> &visitedVec,vector<vector<int> > &result){ // 形成一个全排列 if(num.size() == visitedVec.size()){ result.push_back(visitedVec); return; }//if for(int i = 0;i < num.size();++i){ // 重复元素 if(i > 0 && !visited[i-1] && num[i] == num[i-1]){ continue; }//if // 如果没有访问过 if(visited[i] == false){ visited[i] = true; visitedVec.push_back(num[i]); DFS(num,visited,visitedVec,result); visitedVec.pop_back(); visited[i] = false; }//if }//for } }; int main(){ Solution solution; vector<int> num; num.push_back(1); num.push_back(1); num.push_back(2); // 重新排列 vector<vector<int> > permutes = solution.permuteUnique(num); // 输出 for(int i = 0;i < permutes.size();i++){ cout<<"["; for(int j = 0;j < permutes[i].size();j++){ cout<<permutes[i][j]; }//for cout<<"]"<<endl; } return 0; }
标签:
原文地址:http://blog.csdn.net/sunnyyoona/article/details/42871661