如何按字典序从小到大输出前 n 个数的所有排列?
递归调用将数字分成两部分:
每次移除一个待定元素添加到前缀序列末尾,进行下一次递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void print_permutation ( int n , int * A , int cur ) {
if ( cur == n ) { //递归边界
for ( int i = 0 ; i < n ; i ++ ) printf ( "%d " , A [ i ]);
printf ( " \n " );
}
else for ( int i = 1 ; i <= n ; i ++ ) { //尝试在 A[cur] 中填各种整数 i
int ok = 1 ;
for ( int j = 0 ; j < cur ; j ++ )
if ( A [ j ] == i ) ok = 0 ; //如果 i 已经在 A[0]~A[cur-1] 出现过,则不能再选
if ( ok ) {
A [ cur ] = i ;
print_permutation ( n , A , cur + 1 ); //递归调用
}
}
}
直接生成该方法直接获取到排列序列
将元素排序,记录初始序列。 将当前首元素记录。 每次将记录的元素右移 1 位(交换位置),生成一个排列 直到元素移到最右边,回到步骤 2 当出现了初始序列时,排列生成完毕 具体代码可以参照 std 标准库里面的方法next_permutation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<cstdio>
#include<algorithm> //包含 next_permutation
using namespace std ;
int main ( ) {
int n , p [ 10 ];
scanf ( "%d" , & n );
for ( int i = 0 ; i < n ; i ++ ) scanf ( "%d" , & p [ i ]);
sort ( p , p + n ); //排序,得到 p 的最小排列
do {
for ( int i = 0 ; i < n ; i ++ ) printf ( "%d " , p [ i ]); //输出排列 p
printf ( " \n " );
} while ( next_permutation ( p , p + n )); //求下一个排列
return 0 ;
}