iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现LeetCode(46.全排列)
  • 695
分享到

C++实现LeetCode(46.全排列)

2024-04-02 19:04:59 695人浏览 八月长安
摘要

[LeetCode] 46. Permutations 全排列 Given a collection of distinct integers, return a

[LeetCode] 46. 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++实现LeetCode(46.全排列)的文章就介绍到这了,更多相关C++实现全排列内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++实现LeetCode(46.全排列)

本文链接: https://www.lsjlt.com/news/130487.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • C++实现LeetCode(46.全排列)
    [LeetCode] 46. Permutations 全排列 Given a collection of distinct integers, return a...
    99+
    2024-04-02
  • C++实现LeetCode(47.全排列之二)
    [LeetCode] 47. Permutations II 全排列之二 Given a collection of numbers that might contain dupli...
    99+
    2024-04-02
  • C++实现LeetCode(60.序列排序)
    [LeetCode] 60. Permutation Sequence 序列排序 The set [1,2,3,...,n] contains a total o...
    99+
    2024-04-02
  • C++实现LeetCode(31.下一个排列)
    [LeetCode] 31. Next Permutation 下一个排列 Implement next permutation, which rearranges num...
    99+
    2024-04-02
  • C++怎么实现全排列
    这篇文章主要讲解了“C++怎么实现全排列”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++怎么实现全排列”吧!Permutations 全排列Given a collection of&n...
    99+
    2023-06-20
  • c语言回溯全排列怎么实现
    可以使用递归的方式实现回溯法求全排列。具体步骤如下:1. 定义一个递归函数 `backtrack()`,该函数有两个参数:`nums...
    99+
    2023-09-08
    c语言
  • c语言全排列算法怎么实现
    以下是一个用C语言实现全排列的算法示例: #include <stdio.h> #include <string....
    99+
    2024-04-02
  • C++实现LeetCode(75.颜色排序)
    [LeetCode] 75. Sort Colors 颜色排序 Given an array with n objects colored red, white ...
    99+
    2024-04-02
  • C++实现LeetCode(148.链表排序)
    [LeetCode] 148. Sort List 链表排序 Sort a linked list in O(n log n) time using c...
    99+
    2024-04-02
  • c++全排列的递归算法怎么实现
    下面是C++中全排列的递归算法的实现:```cpp#include #include using namespace std;// ...
    99+
    2023-09-28
    c++
  • C++实现LeetCode(143.链表重排序)
    [LeetCode] 143.Reorder List 链表重排序 Given a singly linked list L: L0→L1→…→Ln-1→Ln, ...
    99+
    2024-04-02
  • C++实现LeetCode(147.链表插入排序)
    [LeetCode] 147. Insertion Sort List 链表插入排序 Sort a linked list using insertion sort. A graph...
    99+
    2024-04-02
  • C#SortedList排序列表的实现
    目录SortedList 类的中的属性SortedList 类的中的方法在 C# 中,SortedList 类用来表示键/值对的集合,这些键/值对按照键值进行排序,并且可以通过键或索...
    99+
    2023-05-14
    C# SortedList排序列表 C# 排序列表
  • C++如何实现序列排序
    这篇文章主要讲解了“C++如何实现序列排序”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++如何实现序列排序”吧!Permutation Sequence 序列排序The set ...
    99+
    2023-06-19
  • C++实现LeetCode(171.求Excel表列序号)
    [LeetCode] 171.Excel Sheet Column Number 求Excel表列序号 Related to question Excel Sheet Column ...
    99+
    2024-04-02
  • Java算法如何实现全排列
    本篇内容主要讲解“Java算法如何实现全排列”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java算法如何实现全排列”吧!算法一基于递归与回溯实现。在排列1,2,3的时候,先由3向上回溯到2发现...
    99+
    2023-07-02
  • C++实现LeetCode(168.求Excel表列名称)
    [LeetCode] 168.Excel Sheet Column Title 求Excel表列名称 Given a positive integer, return its cor...
    99+
    2024-04-02
  • go语言如何实现全排列
    今天小编给大家分享一下go语言如何实现全排列的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。思路:首先画出全排列的树形结构,以...
    99+
    2023-07-05
  • java全排列算法怎么实现
    以下是一种实现Java全排列算法的方法:```javaimport java.util.ArrayList;import java....
    99+
    2023-09-26
    java
  • C++实现LeetCode(115.不同的子序列)
    [LeetCode] 115. Distinct Subsequences 不同的子序列 Given a string S and a string T...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作