一、前言
标签:全排序、回溯法。
问题来源LeetCode 46 难度:中等。
问题链接:https://leetcode-cn.com/problems/permutations/
二、题目
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例 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 个空格,在程序中我们可以用「回溯法」来模拟这个过程。具体过程看代码一目了然。
四、编码实现
//==========================================================================
/*
* @file : 046_Permute.h
* @label : 全排序、回溯法
* @blogs : https://blog.csdn.net/nie2314550441/article/details/107525867
* @author : niebingyu
* @date : 2020/07/21
* @title : 46.全排列
* @purpose : 给定一个 没有重复 数字的序列,返回其所有可能的全排列。
*
* 示例1:
* 输入: [1,2,3]
* 输出:
* [
* [1,2,3],
* [1,3,2],
* [2,1,3],
* [2,3,1],
* [3,1,2],
* [3,2,1]
* ]
*
*
* 来源:力扣(LeetCode)
* 难度:中等
* 链接:https://leetcode-cn.com/problems/permutations/
*/
//==========================================================================
#pragma once
#include <iostream>
#include <vector>
#include <algorithm>
#include <assert.h>
using namespace std;
#define NAMESPACE_PERMUTE namespace NAME_PERMUTE {
#define NAMESPACE_PERMUTEEND }
NAMESPACE_PERMUTE
class Solution
{
public:
vector<vector<int>> permute(vector<int>& nums)
{
if (nums.empty()) return { {} };
vector<vector<int>> ans;
permute(nums, 0, ans);
return ans;
}
private:
void permute(vector<int>& nums, int index, vector<vector<int>>& ans)
{
if (index == nums.size())
{
ans.emplace_back(nums);
return;
}
for (int i = index; i < nums.size(); ++i)
{
// 动态维护数组
swap(nums[i], nums[index]);
// 继续递归填下一个数
permute(nums, index + 1, ans);
// 撤销操作
swap(nums[i], nums[index]);
}
}
};
以下为测试代码//
// 测试 用例 START
void test(const char* testName, vector<int>& nums, vector<vector<int>>& expect)
{
Solution s;
vector<vector<int>> result = s.permute(nums);
if (result == expect)
cout << testName << ", solution passed." << endl;
else
cout << testName << ", solution failed. " << endl;
}
// 测试用例
void Test1()
{
vector<int> nums = { 1,2,3 };
vector<vector<int>> expect = { {1,2,3}, {1,3,2}, {2,1,3}, {2,3,1}, {3,2,1}, {3,1,2} };
test("Test1()", nums, expect);
}
NAMESPACE_PERMUTEEND
// 测试 用例 END
//
void Permute_Test()
{
cout << "------ start 46.全排列 ------" << endl;
NAME_PERMUTE::Test1();
cout << "------ end 46.全排列 --------" << endl;
}
执行结果: