46. 全排列

在这里插入图片描述
经典回溯,看成一棵树,就是选择和不选择的过程,如果已经有这个数了,就不能选择这个数了,走到叶子结点后会自动回溯,记得在回上一层时pop_back当前层的数字。

class Solution {
public:
    void dfs(vector<int>&nums){
        if(tmp.size() == nums.size()){
            res.push_back(tmp);
            return;
        }
        for(int i = 0; i < nums.size(); ++i){
            //dfs里的for循环,其实是一个选择的过程,就是在当前结点下的子结点中选择
            //而这里的递归式dfs其实就是进入下一层
            //每次在当前层的dfs的pop_back其实就是在回到上一层的同时将最后一个结点弹出
            if(find(tmp.begin(),tmp.end(),nums[i]) != tmp.end()) continue;
            tmp.push_back(nums[i]);
            dfs(nums);
            tmp.pop_back();
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        //排列=回溯算法,允许数字重复但不允许顺序重复,重点是怎么回
        dfs(nums);
        return res;
    }
private:
    vector<int> tmp;
    vector<vector<int>> res;
};

二刷

class Solution {
public:
    void dfs(vector<int>& nums){
        if(tmp.size() == nums.size()){
            res.push_back(tmp);
            return;
        }
        for(int i = 0; i < nums.size(); ++i){
            if(find(tmp.begin(),tmp.end(),nums[i]) == tmp.end()){
                tmp.push_back(nums[i]);
                dfs(nums);
                tmp.pop_back();
            }
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        //没有重复数字的全排列,easy,dfs即可,只要当前组合中没有要加进去的这个数字就加进去
        //每一层只要考虑当前层能加哪些数字就行了
        if(nums.size() == 0) return res;
        dfs(nums);
        return res;
    }   
private:
    //全局变量要自己手动弹出,局部变量不用但是要传参
    vector<int> tmp;
    vector<vector<int>> res;
};

没有重复数字的数组,直接find出tmp中是否有当前数字即可,如果没有就加入,然后继续dfs

class Solution {
public:
    void dfs(vector<int>& nums){
        if(tmp.size() == nums.size()){
            res.push_back(tmp);
            return;
        }
        for(int i = 0; i < nums.size(); ++i){
            if(find(tmp.begin(),tmp.end(),nums[i]) != tmp.end()) continue;
            tmp.push_back(nums[i]);
            dfs(nums);
            tmp.pop_back();
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        //dfs+回溯,注意在tmp中的不要再加进去了
        dfs(nums);
        return res;
    }
private:
    vector<vector<int>> res;
    vector<int> tmp;
};
class Solution {
public:
    //因为是通过for循环控制的,不用担心下标越界
    void dfs(vector<int>& nums){
        if(tmp.size() == nums.size()){
            //此处不需要弹出,在哪里加入在哪里弹出就行了
            res.push_back(tmp);
            return;
        }
        for(int i = 0; i < nums.size(); ++i){
            if(find(tmp.begin(),tmp.end(),nums[i]) == tmp.end()){
                tmp.push_back(nums[i]);
                dfs(nums);
                tmp.pop_back();
            }
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        //普通的回溯
        dfs(nums);
        return res;
    }
private:
    vector<vector<int>> res;
    vector<int> tmp;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值