Bootstrap

LeetCode46.全排列

在这里插入图片描述

LeetCode刷题记录


📜题目描述

给定一个不含重复数字的数组 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
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

💡解题思路

思路:经典回溯

image-20221114180103280

每个节点:

  • 前序位置:
    1. 当前元素放入临时vector tmp
    2. 标记当前元素已经使用过了used[i] = true
    3. 判断tmp的长度是否和nums的长度相同,若相同则为全排列,尾插到结果数组
  • 中序位置:递归 – 遍历nums,递归没有使用过的元素
  • 后序位置:撤销操作(回溯)
    1. used[i] = false (当前值标记为未使用)
    2. tmp.pop_back() (临时数组删除当前元素)

主函数中需要遍历每一个元素为起始

for(i : nums)

C++代码

class Solution {  
public:  
    void backtrack(vector<vector<int>>& vv, vector<bool>& used, const vector<int>& nums, vector<int>& tmp) {  
        //结束条件  
        if (tmp.size() == nums.size()) { //走到最底了  
            vv.push_back(tmp);  
            return;  
        }  
        for (int i = 0; i < nums.size(); ++i) {  
            if (used[i]) {  
                //如果被使用,continue  
                continue;  
            }  
            //如果当前元素没有被使用  
            //操作  
            used[i] = true;  
            tmp.push_back(nums[i]);  
            //递归问题 -> 临时变量的是 tmp 和 used数组  
            backtrack(vv, used, nums, tmp);  
            //撤销操作  
            used[i] = false;  
            tmp.pop_back();  
        }  
    }  
    vector<vector<int>> permute(vector<int>& nums) {  
        int len = nums.size();  
        //设立一个标记数组。  
        vector<bool> used(len, false);  
        //保存最终结果  - 长度未知  
        //临时容器  
        vector<int> tmp;  
        vector<vector<int>> vv;  
        backtrack(vv, used, nums, tmp);  
        return vv;  
    }  
};
;