一,题目描述:
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
二,解题思路:
采用不断交换两个位置的方法获得所有的排列,即以某个点为开始点,依次和后面的做交换,因为没有重复项,所以得到的序列都是不同的结果,例如
1 2 3
/*
* 开始点为第一个数
* 1和2交换 ->2 1 3
* 1和3交换 ->3 2 1
*/
2 1 3
/*
* 从2 1 3递归
* 开始点为第二个数
* 1和3交换 ->2 3 1
*/
3 2 1
/*
* 从3 2 1递归
* 开始点为第二个数
* 2和1交换 ->3 1 2
*/
/* 结果 */
1 2 3
2 1 3
2 3 1
3 1 2
3 2 1
但是这种方法少了一种结果,{1 3 2}
。因为序列{1 2 3}的时候是以1为开始点,但是没有对2和3进行交换。解决办法就是当开始点进行交换时,也要和自己交换一次,但是交换的结果不能添加到结果中。但是这样对于第一个序列{1 2 3}
就不在结果中,所以需要在交换前手动添加第一个序列。
三,C++代码:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
/* 添加最初的序列 */
res.push_back(nums);
get_permutation(nums, 0, res);
return res;
}
private:
void get_permutation(vector<int>& nums, int idx, vector<vector<int>>& res)
{
if(idx >= nums.size())
return;
/* 以idx位置作为开始点,依次和后面的交换 */
for(int i = idx; i < nums.size(); ++i)
{
/* 交换,获取一个排列 */
swap(nums[i], nums[idx]);
/* 如果不是自己和自己交换,就把排列添加到结果中 */
if(i != idx)
res.push_back(nums);
/* 递归调用,以下一个位置作为开始点 */
get_permutation(nums, idx + 1, res);
/* 交换完再换回来,回到开始的状态,然后和下一个交换 */
swap(nums[i], nums[idx]);
}
}
};
---------------------
作者:一个程序渣渣的小后院
来源:CSDN
原文:https://blog.csdn.net/sinat_35261315/article/details/78406927
版权声明:本文为博主原创文章,转载请附上博文链接!