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]
.
解法1:采用将当前元素与后续元素交换,并递归实现的方法
int len; bool isSwap(vector<int> & nums, int s, int e){//查找重复元素,如果前面已经出现过该元素,最后返回false,不会替换 while(nums[s]!=nums[e]&&s<e) s++; if(s==e)return true; else return false; } void generate(vector<vector<int>> & ret, vector<int> & nums, int cur){ if(len==cur+1){ ret.push_back(nums); } else{ for(int i=cur; i<len; i++){ if(!isSwap(nums, cur, i)) continue;//如果前面出现过该元素,则不执行交换,因为cur元素已经跟前面的元素发生过替换,替换后,在generate(ret, nums, cur+1)已经直接或间接的跟该元素发生过替换,所以不要再次交换 swap(nums[cur], nums[i]); generate(ret, nums, cur+1); swap(nums[cur], nums[i]); } } } vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> ret; len=nums.size(); sort(nums.begin(), nums.end());//首先对数据序列进行排序,使相同元素挨着 generate(ret, nums, 0); return ret; }
解法2.采用字典序的方法,使用非递归排序方法
vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> ret; if(nums.size()<=0) return ret; int len=nums.size(); sort(nums.begin(), nums.end());//首先对数据序列进行排序,是相同元素挨着 ret.push_back(nums); int min; int nextMin; int start; int end; while(true){ min=len-2; nextMin=len-1; while(min>=0 && nums[min]>=nums[min+1] ) min--;//1. 从后往前找第一个比右边数据小的元素 if(min==-1) break; while(nextMin>min && nums[nextMin]<=nums[min])nextMin--;//2. 从后往前找第一个比nums[min]大的数据 swap(nums[nextMin], nums[min]);//3. 交换数据 start=min+1; end=len-1; while(start<end){//后面的数据保持从小到大排序 swap(nums[start], nums[end]); start++; end--; } ret.push_back(nums); } return ret; }
以上两种方法在leetcode的执行时间都是32ms
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/jisuanji_wjfioj/article/details/46931381