Permutations
Given a collection of numbers, return all possible permutations.
For example,
题目主要是为了对数字进行全排列[1,2,3]
have the following permutations:[1,2,3]
,[1,3,2]
,[2,1,3]
,[2,3,1]
,[3,1,2]
, and[3,2,1]
.
想到的办法是将一个数字放到第一位,其余的数字进行全排列,因此需要用递归算法,最后递归返回的vector中的每一个vector,并将第一个数据补充至第一个位置
注意一些vector的函数:
cur.erase(cur.begin()+i); //<删除对应的元素,容器的大小发生了改变
tmp.insert(tmp.begin(), num[i]);
class Solution { public: vector<vector<int> > permute(vector<int> &num) { vector<int>::size_type N = num.size(); vector<vector<int> > ret; vector<int> cur; vector<int> tmp; if(N == 1) { ret.push_back(num); return ret; } vector<vector<int> > post; for(int i = 0; i < N; i++) { cur = num; cur.erase(cur.begin()+i); //<删除对应的元素,容器的大小发生了改变 post = permute(cur); for(int j = 0; j < post.size(); j++) { tmp = post[j]; tmp.insert(tmp.begin(), num[i]); ret.push_back(tmp); } } return ret; } };
在网上还看到很多别的方法:
全排列类似于树结构:
从根节点即为给出的数字的集合
第一层节点为为num[0]和之后的数字一一交换的结果
第二层实在第一层的结果上num[1]和之后的数字一一交换的过程
依次类推,叶子节点就是想要的结果:
举个例子
123
123 213 321 i= 0
123 132 213 231 321 312 i= 1
123 132 213 231 321 312 i= 2
最后一层则是直接退出
class Solution { vector<vector<int> > ret; int N; public: void perm(vector<int> &num, int i){ if( i == N){ ret.push_back(num); } for(int j = i; j < N; j++){ swap(num[i], num[j]); perm(num, i + 1); swap(num[j], num[i]); } } vector<vector<int> > permute(vector<int> &num) { // Start typing your C/C++ solution below // DO NOT write int main() function N = num.size(); ret.clear(); perm(num, 0); return ret; } };
stl的algorithm有next permutation的算法的next permutation的算法就是。。。swap + reverse。。。(具体怎么实现全排列还需要自己掌握)class Solution { public: void nextPermutation(vector<int> &num) { // Start typing your C/C++ solution below // DO NOT write int main() function //5,4,7,5,3,2 // | | // i j //5,5,7,4,3,2 //5,5,2,3,4,7 int i = num.size()-1; while(i > 0 && num[i-1] >= num[i] ){ i--; } int j = i; while(j < num.size() && num[j] > num[i-1]) j++; if(i == 0){ reverse(num.begin(), num.end()); }else{ swap(num[i-1], num[j-1]); reverse(num.begin() + i, num.end()); } } int factorial(int n){ return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n; } vector<vector<int> > permute(vector<int> &num) { // Start typing your C/C++ solution below // DO NOT write int main() function int N = num.size(); vector<vector<int> > ret; ret.push_back(num); for(int i = 1; i < factorial(N); i++){ nextPermutation(num); ret.push_back(num); } return ret; } };
补充说明:
erase函数的定义,通过迭代器来删除单个或者范围的元素
iterator erase( iterator _Where ); iterator erase( iterator _First, iterator _Last );
remove函数的定义
template<class _FwdIt, class _Ty> inline _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty% _Val);
与erase不同的是,remove函数删除元素后并不会改变vector的大小,只是把后面的元素往前移,并返回一个指向vector末尾的新迭代器。