题目
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
分析
设R = { r1, r2, … , rn}是要进行排列的n个元素,Ri = R = { ri }。集合X中元素的全排列记为prem(X)。(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀 ri得到的排列。
R的全排列可归纳定义为:
- 当n = 1时,perm ( R ) = ( r ),其中 r 是集合R中唯一的元素;
- 当n > 1时,perm(R)由 (r1)perm(R1), (r2)perm(R2), … , (r n)perm(Rn)构成。
实际上,在分析递归的时候,需要按层序分析,理解了一层的概念,就能理解每一层。
图示:
若R = { 1, 2, 3 };那么可以得到下面这样的写法
再往下递归可得到:
那么问题就是,如何从 (1)Perm(2,3) 转换成 (2)Perm(1, 3),做法就是让两个下标的值相交换。
代码
#include<iostream>
using namespace std;
void Perm(int* nums, int i, int m)
{
if (i == m) // 当满足此条件,说明只剩一个数据,无法递归
{
for (int j = 0; j <= m; ++j)
{
cout << nums[j] << " ";
}
cout << endl;
}
else
{
for (int j = i; j <= m; ++j)
{
std::swap(nums[i], nums[j]);
Perm(nums, i + 1, m);
// 撤销交换
std::swap(nums[i], nums[j]);
}
}
}
int main(void)
{
int nums[3] = { 1, 2, 3 };
int n = 3;
Perm(nums, 0, n - 1);
return 0;
}
运行结果:
借鉴: