1、全排列
问题描述
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
解题思路
- 基本思路是递归加回溯。
- 这个问题转化为从左到右
n
个空行,n
个数,每个数每次都只能使用一次,依次放入到所有的不同的n
个空行中,返回所有的可能排列结果,即为全排列。使用函数递归和回溯法来解决这个问题。 - 随着递归的深入,直到元素序列只剩下最后两个时,将其交换。递归回退到上一层。随着循环,将在该层递归的前提下,序列从左到右依次与该层递归中的序列第一个元素交换,每交换一次后,再次进入递归将这这种情况下的所有可能结果随着递归排列完毕。在以该层递归的所有情况排列完毕后,递归函数回退到再上一层,再进行漫长地以该层递归为首的元素与其后面的所有元素交换再递归。以此类推,直到整个序列中的第一个元素与所有元素交换完毕并依次完成所有全排列后,算法结束,全排列完成。
- 下图是
LeetCode
中的官方题解中的动态图。
代码实现
class Solution {
public:
void backtrack(vector<vector<int>>& res, vector<int>& nums, int index, int len){
if (index == len) {
res.push_back(nums);
return;
}
for (int i = index; i < len; i++) {
// 动态维护数组
swap(nums[i], nums[index]);
// 继续递归填下一个数
backtrack(res, nums, index + 1, len);
// 撤销操作
swap(nums[i], nums[index]);
}
}
vector< vector<int> > permute(vector<int>& nums) {
vector< vector<int> > res;
int len = nums.size();
backtrack(res, nums, 0, len);
return res;
}
};
//他如果输入的是{1, 2, 3}的话,打印结果是:
/*
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
请按任意键继续. . .
*/
运行截图
在VS2013上的运行情况
#include<iostream>
#include<vector>
#include<algorithm>
using namesapce std;
void backtrack(vector< vector<int> >