排列
一.next_permutation()函数
STL中求“下一个“全排列的函数是next_permutation()。
它的定义有两种形式:
next_permutation(_BIter, _BIter);
next_permutation(_BIter, _BIter, _Compare);
如果没有下一个排列方式,返回false,否则返回true,并把新的排列放到原来的空间里。
注意,函数的排列范围为[first,last]包括first,不包括last
如果你想得到所有的全排列,那么初始要用sort函数排序,是数组为最小的排列,因为next_permutation()函数是逐渐把序列变大的,而不是一开始就是全部的排列。
二.手写排列函数
思路:用数组b记录一个新的全排列,每次递归在剩下的数中选一个,并用vis数组判重
#include <iostream> using namespace std; int a[20]={1,2,3,4,5,6,7,8,9,10}; bool vis[20]; int b[20]; void dfs(int s,int t) { if(s==t)//所有数都选过了 { //输出全排列 for(int i=0;i<t;i++) cout << b[i] << " "; cout << endl; return ; } for(int i=0;i<t;i++) { if(!vis[i])//这个数没有被选过 { vis[i]=true; b[s]=a[i]; dfs(s+1,t); vis[i]=false;//回溯 } } } int main() { ios::sync_with_stdio(false); int n=3; dfs(0,n);//生成前n个数的全排列 return 0; }
时间复杂度为O(n!)
三.实战
代码:
#include <bits/stdc++.h> using namespace std; int a[20]; bool vis[20]; int b[20]; int n; void dfs(int s,int t) { if(s==t) { for(int i=0;i<t;i++) cout << setw(5) << b[i]; cout << endl; return ; } for(int i=0;i<t;i++) { if(!vis[i]) { vis[i]=true; b[s]=a[i]; dfs(s+1,t); vis[i]=false; } } } int main() { ios::sync_with_stdio(false); cin>>n; for(int i=0;i<n;i++) a[i]=i+1; dfs(0,n); return 0; }
只需略微修改即可AC。