• 【回溯算法】leetcode 46. 全排列


    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 < = n u m s . l e n g t h < = 6 1 <= nums.length <= 6 1<=nums.length<=6
    • − 10 < = n u m s [ i ] < = 10 -10 <= nums[i] <= 10 10<=nums[i]<=10
    • n u m s 中的所有整数互不相同 nums 中的所有整数 互不相同 nums中的所有整数互不相同

    方法:回溯算法

    解题思路

    使用 回溯三部曲

    • 递归函数参数

    排列是有序的,所以需要一个 u s e d used used 数组,标记已经选择过的元素

    vector<vector<int>> result;
    vector<int> path;
    void backtracking (vector<int>& nums, vector<bool>& used)
    
    • 1
    • 2
    • 3
    • 递归终止条件

    当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列。

    // 此时说明找到了一组
    if (path.size() == nums.size()) {
        result.push_back(path);
        return;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 单层搜索的逻辑

    因为排列问题,每次都要从头开始搜索,例如元素 1 在 [1,2] 中已经使用过了,但是在 [2,1] 中还要再使用一次 1。

    u s e d used used 数组,其实就是记录此时 p a t h path path 里都有哪些元素使用了,一个排列里一个元素只能使用一次。

    for (int i = 0; i < nums.size(); i++) {
        if (used[i] == true) continue; 
        used[i] = true;
        path.push_back(nums[i]);
        backtracking(nums, used);
        path.pop_back();
        used[i] = false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码

    class Solution {
    public:
        vector<vector<int>> result;
        vector<int> path;
        void dfs(vector<int>& nums, vector<bool>& used) {
            if(path.size() == nums.size()) {
                result.push_back(path);
                return;
            }
            for(int i = 0; i < nums.size(); i++) {
                if(!used[i]) {
                    used[i] = true;
                    path.push_back(nums[i]);
                    dfs(nums, used);
                    used[i] = false;
                    path.pop_back();
                }
            }
        }
        vector<vector<int>> permute(vector<int>& nums) {
            vector<bool> used(nums.size(), false);
            dfs(nums, used);
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    复杂度分析

    • 时间复杂度: O ( n × n ! ) O(n \times n!) O(n×n!)
    • 空间复杂度: O ( n ) O(n) O(n)
  • 相关阅读:
    SOLIDWORKS二次开发——拓展设计能力与定制化解决方案
    电子台账之自定义财务报表模板
    【Servlet】Servlet API 详解
    C语言关于&与&&运算符
    商圣范蠡见好就收,散尽钱财求得好死
    数据治理-数据质量监控
    MacOs 删除第三方软件
    [排序]leetcode1636:按照频率将数组升序排序(easy)
    化妆品用乙基己基甘油全球市场总体规模2023-2029
    Java基础学习——动态绑定机制
  • 原文地址:https://blog.csdn.net/lele_ne/article/details/126611310