IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> [算法题解详细]DFS解力扣46全排列 -> 正文阅读

[数据结构与算法][算法题解详细]DFS解力扣46全排列

题目

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例1

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例2

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例3

输入:nums = [1]
输出:[[1]]

提示

 1 <= nums.length <= 6
 2. -10 <= nums[i] <= 10
 3. nums 中的所有整数 互不相同

思路

首先我们要明白排列的概念以及和组合的区别

所谓排列,就是指从给定个数的元素中取出指定个数的元素进行排序。组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。

这里我画了一下示例1的图示,如果对排列有不理解的可以看这张图理解
请添加图片描述
可以看到在每一层递归中我们都会选择一个数字,当选择的数字到达3个后我们把当前的排列加入答案中,然后通过逐级回溯到上层递归去寻找其他的排列,下面我们看代码

代码

首先在主函数中我们要定义一个bool类型的容器,这个容器的作用是用于在递归的时候去跳过当前我们已经在之前选中的数字,结合上面的图我们可以看到:
在第一层中我们选中了1,下一层中就只有2,3可以选择了
同样,如果第一层选中的是2,下一层中就只有1,3可以选择了
如果第一层选中的是3,下一层中就只有1,2可以选择了

因此我们想要知道在当前递归之前我们已经选中了哪些数字,就需要定义一个bool类型的数组或容器,用来标识数组中哪些数字已经被使用了,而这个bool类型的数组或容器大小与题目所给的nums数组是一致的

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> temp;
    int n;
    vector<vector<int>> permute(vector<int>& nums) {
        n = nums.size();
        vector<bool> record(n, false);
        dfs(0, nums, record);
        return ans;
    }
};

然后进入dfs函数,出口条件就是递归深度等于了数组长度的时候,同时也是选中了所有的数字的时候,把当前的排列加入答案中,然后回溯到上一层

void dfs(int u, vector<int>& nums, vector<bool>& record) {
        if(u == n) {
            ans.push_back(temp);
            return;
        }
}

然后要注意在每一层中,我们都遍历数组nums,在循环中判断如果当前nums[i]在record数组中还没有使用过,也就是!record[i]为真时,则把当前nums[i]加入排列中
然后就是一个回溯的写法,进入下一层之间把record[i]置成true表示在下一层递归中当前数字已经使用了,在下一层递归结束后把record[i]又置成false,回溯到进入下一层递归前的状态

void dfs(int u, vector<int>& nums, vector<bool>& record) {
        if(u == n) {
            ans.push_back(temp);
            return;
        }
        for(int i = 0; i < n; i++) {
            if(!record[i]) {
                record[i] = true;
                temp.push_back(nums[i]);
                dfs(u + 1, nums, record);
                temp.pop_back();
                record[i] = false;
            }
        }
    }

然后把代码整合起来
完整代码:

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> temp;
    int n;
    void dfs(int u, vector<int>& nums, vector<bool>& record) {
        if(u == n) {
            ans.push_back(temp);
            return;
        }
        for(int i = 0; i < n; i++) {
            if(!record[i]) {
                record[i] = true;
                temp.push_back(nums[i]);
                dfs(u + 1, nums, record);
                temp.pop_back();
                record[i] = false;
            }
           
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        n = nums.size();
        vector<bool> record(n, false);
        dfs(0, nums, record);
        return ans;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-11 12:57:43  更:2021-11-11 12:57:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:48:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码