我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++怎么实现全排列

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++怎么实现全排列

这篇文章主要讲解了“C++怎么实现全排列”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++怎么实现全排列”吧!

Permutations 全排列

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

这道题是求全排列问题,给的输入数组没有重复项,这跟之前的那道 Combinations 和类似,解法基本相同,但是不同点在于那道不同的数字顺序只算一种,是一道典型的组合题,而此题是求全排列问题,还是用递归 DFS 来求解。这里需要用到一个 visited 数组来标记某个数字是否访问过,然后在 DFS 递归函数从的循环应从头开始,而不是从 level 开始,这是和 Combinations 不同的地方,其余思路大体相同。这里再说下 level 吧,其本质是记录当前已经拼出的个数,一旦其达到了 nums 数组的长度,说明此时已经是一个全排列了,因为再加数字的话,就会超出。还有就是,为啥这里的 level 要从0开始遍历,因为这是求全排列,每个位置都可能放任意一个数字,这样会有个问题,数字有可能被重复使用,由于全排列是不能重复使用数字的,所以需要用一个 visited 数组来标记某个数字是否使用过,代码如下:

解法一:

class Solution {public:    vector<vector<int>> permute(vector<int>& num) {        vector<vector<int>> res;        vector<int> out, visited(num.size(), 0);        permuteDFS(num, 0, visited, out, res);        return res;    }    void permuteDFS(vector<int>& num, int level, vector<int>& visited, vector<int>& out, vector<vector<int>>& res) {        if (level == num.size()) {res.push_back(out); return;}        for (int i = 0; i < num.size(); ++i) {            if (visited[i] == 1) continue;            visited[i] = 1;            out.push_back(num[i]);            permuteDFS(num, level + 1, visited, out, res);            out.pop_back();            visited[i] = 0;        }    }};

上述解法的最终生成顺序为:[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]] 。

还有一种递归的写法,更简单一些,这里是每次交换 num 里面的两个数字,经过递归可以生成所有的排列情况。这里你可能注意到,为啥在递归函数中, push_back() 了之后没有返回呢,而解法一或者是 Combinations 的递归解法在更新结果 res 后都 return 了呢?其实如果你仔细看代码的话,此时 start 已经大于等于 num.size() 了,而下面的 for 循环的i是从 start 开始的,根本就不会执行 for 循环里的内容,就相当于 return 了,博主偷懒就没写了。但其实为了避免混淆,最好还是加上,免得和前面的搞混了,代码如下:

解法二:

class Solution {public:    vector<vector<int>> permute(vector<int>& num) {        vector<vector<int>> res;        permuteDFS(num, 0, res);        return res;    }    void permuteDFS(vector<int>& num, int start, vector<vector<int>>& res) {        if (start >= num.size()) res.push_back(num);        for (int i = start; i < num.size(); ++i) {            swap(num[start], num[i]);            permuteDFS(num, start + 1, res);            swap(num[start], num[i]);        }    }};

上述解法的最终生成顺序为:[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] 

最后再来看一种方法,这种方法是 CareerCup 书上的方法,也挺不错的,这道题是思想是这样的:

当 n=1 时,数组中只有一个数 a1,其全排列只有一种,即为 a1

当 n=2 时,数组中此时有 a1a2,其全排列有两种,a1a和 a2a1,那么此时考虑和上面那种情况的关系,可以发现,其实就是在 a的前后两个位置分别加入了 a

当 n=3 时,数组中有 a1a2a3,此时全排列有六种,分别为 a1a2a3, a1a3a2, a2a1a3, a2a3a1, a3a1a2, 和 a3a2a1。那么根据上面的结论,实际上是在 a1a和 a2a的基础上在不同的位置上加入 a而得到的。

_ a_ a_ : a3a1a2, a1a3a2, a1a2a3

_ a_ a_ : a3a2a1, a2a3a1, a2a1a3

解法三:

class Solution {public:    vector<vector<int>> permute(vector<int>& num) {        if (num.empty()) return vector<vector<int>>(1, vector<int>());        vector<vector<int>> res;        int first = num[0];        num.erase(num.begin());        vector<vector<int>> words = permute(num);        for (auto &a : words) {            for (int i = 0; i <= a.size(); ++i) {                a.insert(a.begin() + i, first);                res.push_back(a);                a.erase(a.begin() + i);            }        }           return res;    }};

上述解法的最终生成顺序为:[[1,2,3], [2,1,3], [2,3,1], [1,3,2], [3,1,2], [3,2,1]]

上面的三种解法都是递归的,我们也可以使用迭代的方法来做。其实下面这个解法就上面解法的迭代写法,核心思路都是一样的,都是在现有的排列的基础上,每个空位插入一个数字,从而生成各种的全排列的情况,参见代码如下:

解法四:

class Solution {public:    vector<vector<int>> permute(vector<int>& num) {        vector<vector<int>> res{{}};        for (int a : num) {            for (int k = res.size(); k > 0; --k) {                vector<int> t = res.front();                res.erase(res.begin());                for (int i = 0; i <= t.size(); ++i) {                    vector<int> one = t;                    one.insert(one.begin() + i, a);                    res.push_back(one);                }            }        }        return res;    }};

上述解法的最终生成顺序为:[[3,2,1], [2,3,1], [2,1,3], [3,1,2], [1,3,2], [1,2,3]]

下面这种解法就有些耍赖了,用了 STL 的内置函数 next_permutation(),专门就是用来返回下一个全排列,耳边又回响起了诸葛孔明的名言,我从未见过如此...投机取巧...的解法!

解法五:

class Solution {public:    vector<vector<int>> permute(vector<int>& num) {        vector<vector<int>> res;        sort(num.begin(), num.end());        res.push_back(num);        while (next_permutation(num.begin(), num.end())) {            res.push_back(num);        }        return res;    }};

上述解法的最终生成顺序为:[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]

感谢各位的阅读,以上就是“C++怎么实现全排列”的内容了,经过本文的学习后,相信大家对C++怎么实现全排列这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++怎么实现全排列

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++怎么实现全排列

这篇文章主要讲解了“C++怎么实现全排列”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++怎么实现全排列”吧!Permutations 全排列Given a collection of d
2023-06-20

c语言回溯全排列怎么实现

可以使用递归的方式实现回溯法求全排列。具体步骤如下:1. 定义一个递归函数 `backtrack()`,该函数有两个参数:`nums` 表示待排列的数组,`path` 表示当前已经排好的部分排列。2. 在 `backtrack()` 函数中
2023-09-08

c++全排列的递归算法怎么实现

下面是C++中全排列的递归算法的实现:```cpp#include #include using namespace std;// 交换两个元素的位置void swap(vector& nums, int i, int j) {int te
2023-09-28

java全排列算法怎么实现

以下是一种实现Java全排列算法的方法:```javaimport java.util.ArrayList;import java.util.List;public class Permutation {public static void
2023-09-26

java字符串全排列怎么实现

可以使用递归的方法来实现字符串的全排列。具体步骤如下:定义一个递归函数,传入一个字符串和两个索引参数,分别表示当前排列的起始位置和结束位置。如果起始位置等于结束位置,表示已经完成了一次排列,将当前字符串输出。否则,将当前字符串分为两部
2023-10-21

java全排列用递归怎么实现

要实现全排列的递归算法,可以按照以下步骤进行:1. 定义一个递归函数,传入当前需要排列的数组、起始索引和结束索引。2. 当起始索引等于结束索引时,表示已经遍历到数组的最后一个元素,此时输出当前排列结果。3. 否则,通过循环将当前需要排列的数
2023-08-11

c语言全排列数怎么生成

生成C语言全排列数的一种常见方法是使用递归。以下是一个示例代码:#include // 交换两个元素的值void swap(char *x, char *y) {char temp;temp = *x;*x = *y;*y = temp
2023-10-21

c语言排列组合算法怎么实现

C语言排列组合算法可以通过递归实现。下面是一个示例代码:#include void combination(int arr[], int data[], int start, int end, int index, in
c语言排列组合算法怎么实现
2024-02-29

C++如何实现序列排序

这篇文章主要讲解了“C++如何实现序列排序”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++如何实现序列排序”吧!Permutation Sequence 序列排序The set [1,2
2023-06-19

C语言怎么实现Z字形变换排列

本篇内容介绍了“C语言怎么实现Z字形变换排列”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!题目链接:Z 字形变换方法一—&mda
2023-06-30

C#SortedList排序列表的实现

本文主要介绍了C#SortedList排序列表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-14

C语言全排列回溯算法怎么用

这篇文章主要介绍“C语言全排列回溯算法怎么用”,在日常操作中,相信很多人在C语言全排列回溯算法怎么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言全排列回溯算法怎么用”的疑惑有所帮助!接下来,请跟着小编
2023-06-26

Java算法如何实现全排列

本篇内容主要讲解“Java算法如何实现全排列”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java算法如何实现全排列”吧!算法一基于递归与回溯实现。在排列1,2,3的时候,先由3向上回溯到2发现
2023-07-02

go语言如何实现全排列

今天小编给大家分享一下go语言如何实现全排列的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。思路:首先画出全排列的树形结构,以
2023-07-05

datagridview倒序排列怎么实现

要实现DataGridView的倒序排列,可以使用DataGridView的Sort方法,将排序的方向设置为Descending(降序)。示例代码如下:```csharpdataGridView1.Sort(dataGridView1.Co
2023-10-10

sql倒序排列怎么实现

在 SQL 中,使用 ORDER BY 关键字可以将查询结果按照指定的列进行排序。要倒序排列,可以在 ORDER BY 子句中指定要排序的列,并在列名后面加上 DESC 关键字。下面是一个示例,假设有一个名为 students 的表,其中
sql倒序排列怎么实现
2024-04-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录