一,题目描述:
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
二.思路解析
本题中主要想法是对数组中的元素进行交换。
基本想法是:固定一部分的值,认为是已经处理好的,剩下的部分是我想继续交换的部分(这一部分是一个范围)。所以我们需要知道,哪一部分需要继续交换,比如,我认为我已经固定好下标为0的元素了, 那么我需要交换的范围就是0~nums.size()-1,如果下标0~1的元素已经固定了, 那需要交换的元素就是2~nums.size()-1, .........,依次类推,直到所有的都交换完了,即后面的元素都完成了全排列。此时范围是nums.size()-1~nums.size()-1,这时代表着我已经拍完了一趟,还要继续排其他趟,所以用递归来进行操作。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
if(nums.size() == 0)
return result;
// 全排列开始,此时的范围是0~nums.size()-1
perm(nums, result, 0, nums.size()-1);
return result;
}
void perm(vector<int> &nums, vector<vector<int>> &result, int start, int end)
{
// 当开始与终止相遇,说明已经排完一趟,将当前排完的结果存储
if(start == end)
{
vector<int> cur;
for(int i = 0; i <= start; ++i)
{
cur.push_back(nums[i]);
}
result.push_back(cur);
}
else
{
for(int i = start; i<=end;++i)
{
// 交换元素
swap(nums[i], nums[start]);
// 全排start+1~nums.size()-1的元素
perm(nums, result, start+1, end);
// 交换回去,以便于下次进行全排
swap(nums[i], nums[start]);
}
}
}
};