46全排列

一、前言

标签:全排序、回溯法。

问题来源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;
}

执行结果:

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值