Permutations系列
一. 全排列递归算法
1. 数据没有重复的情况下
算法:每个元素依次与后面的数进行交换
例子:假设元素为123,则递归交换事例如下:
2. 数据有重复的情况下、
算法:在没有数据重复的全排列下,交换需要加上前提条件,即元素应该和后面没有重复出现的数字进行交换,即当访问到第k个元素的时候,如果 [k, j)中,没有元素与num[j]相等,则可以交换num[k],num[j]
二. 全排列的迭代算法
参照STL中的实现,算法如下:
1. 在序列中,从后往前寻找第一对递增的元素对,前面一个数为替换数,位置为替换点
2. 接着依然从后往前寻找第一个大于替换数的元素(一定可以找到),记为A
3. 交换替换数与A,然后反转替换点后面的序列
4. 步骤1中如果没有找到,直接反转整个序列
leetcode 中 Permutation Sequence,
Permutations II
,Next Permutation均使用上面的算法,代码如下:
class Solution { public: //没有重复的情况 vector<vector<int> > permute(vector<int> &num) { ans.clear(); allrange(num, 0, num.size()); return ans; } void allrange(vector<int>& num, int k, int n) { if( k == n ) ans.push_back(num); //扫完最后一个元素的时候,num数组就是一个全排列 for(int i=k; i<n; ++i) { //从k开始,第k个数依次与后面的数进行交换 swap(num[k], num[i]); allrange(num, k+1, n); //交换完,开始进行后面部分的全排列 swap(num[k], num[i]); } } //有重复的情况 vector<vector<int> > permuteUnique(vector<int> &num) { ans.clear(); allrange2(num, 0, num.size()); return ans; } //在[ibegin,iend)中寻找是否有=num[iend]的元素,有则不交换,没有就交换 bool isNeedSwap(vector<int>& num, int ibegin, int iend) { for(int i=ibegin; i<iend; ++i) if( num[i] == num[iend] ) return false; return true; } void allrange2(vector<int>& num, int k, int n) { if( k == n ) ans.push_back(num); //扫完最后一个元素,num数组就是一个全排列 for(int i=k; i<n; ++i) //从k开始,第k个数依次与后面的数进行交换 if( isNeedSwap(num, k, i) ) { //若没有重复,则交换 swap(num[k], num[i]); allrange2(num, k+1, n); //交换完,开始进行后面部分的全排列 swap(num[k], num[i]); } } //求下一个全排列 void nextPermutation(vector<int> &num) { vector<int>::iterator cur = num.end(); vector<int>::iterator pre = cur-1; while( pre != num.begin() ) { --pre; //指向cur前面一个元素 --cur; if( *pre < *cur ) { //第一对递增的元素,pre为替换点,*pre为替换数 cur = --num.end(); while( *pre >= *cur ) --cur; //从后往前寻找第一个大于*pre的元素,并与*pre交换 swap( *pre, *cur ); reverse(pre+1, num.end()); //反转替换点之后的元素 return ; } } reverse(num.begin(), num.end()); //数列已是“最后”的序列是,则直接反转 return ; } private: vector< vector<int> > ans; };
Permutation Sequence
The set [1,2,3,…,n]
contains a total of n! unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.