標籤:style color os io for ar 問題 cti
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].
Permutations 的升級版,依舊是全排列問題,但是序列中可能會出現重複數字。
思路:採用字典序的非遞迴方法。從字典順序最小的一種排列開始,每次獲得字典序剛好比前一個排列大的排列,直到得到字典序最大的排列時,就得到了所有的結果,以字串"abc"為例,"abc"是字典序最小的排列,所有情況按字典序排列為"abc","acb","bac","bca","cba","cab"。
具體步驟為為:
1.字串進行排序,得到字串的最小字典序排列(C0C1C2...Cn),Ci<=Ci+1。
2.從後往前,找到一對相鄰的升序元素CiCi+1,(Ci<Ci+1),如果遍曆完字串找不到這樣的相鄰升序對,說明已經達到了字典序最大的全排列
3.從字串結束位置到位置i遍曆,找到比Ci大的元素Cj,交換Cj的位置
4.將Ci+1到Cn所有的字元逆序,這樣得到的排列剛好比之前的字典序大(因為轉換後Ci+1<Ci+2<...<Cn,為最小字典序)。
5.重複3,4,5過程直到字典序最大。
AC code:
class Solution {public: void swap(int &i,int &j) { int temp=i; i=j; j=temp; } vector<vector<int> > permuteUnique(vector<int> &num) { vector<vector<int>> res; int i,j,n=num.size(); sort(num.begin(),num.end()); res.push_back(num); while(true) { for(i=n-2;i>=0;i--) if(num[i]<num[i+1]) break; if(i<=-1) return res; for(j=n-1;j>i;j--) if(num[j]>num[i]) break; swap(num[i],num[j]); for(int k=i+1;k<(i+1+n)/2;k++) swap(num[k],num[n-(k-i)]); res.push_back(num); } }};