【leetcode】深搜、暴搜、回溯、剪枝(C++)1


一、全排列

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

class Solution 
{
public:
    // 全局变量
    vector<vector<int>> ret;
    vector<int> path;
    bool check[7]; // 该题目最大到6--用以判断每个字符的使用情况
    vector<vector<int>> permute(vector<int>& nums) 
    {
        dfs(nums);
        return ret;
    }
    void dfs(vector<int>& nums) 
    {
        // 递归出口
        if(nums.size() == path.size())
        {
            ret.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) 
        {
            if(check[i] == false)
            {
                path.push_back(nums[i]);
                check[i] = true; // 标记用过了
                dfs(nums); // 递归
                // 回溯
                path.pop_back();
                check[i] = false;
            }
        }
    }
};

3、解析

在这里插入图片描述

二、子集

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

代码1:

class Solution 
{
public:
    // 全局变量
    vector<vector<int>> ret;
    vector<int> path;
    vector<vector<int>> subsets(vector<int>& nums) 
    {
        dfs(nums, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos)
    {
        // 1、递归出口
        if(pos == nums.size())
        {
            ret.push_back(path);
            return;
        }
        // 2、选
        path.push_back(nums[pos]);
        dfs(nums, pos + 1); // 递归到下一层
        path.pop_back(); // 恢复现场
        // 3、不选
        dfs(nums, pos + 1);
    }
};

代码2:

class Solution 
{
public:
    // 全局变量
    vector<vector<int>> ret;
    vector<int> path;
    vector<vector<int>> subsets(vector<int>& nums) 
    {
        dfs(nums, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos)
    {
        // 1、递归出口
        ret.push_back(path);
        // 2、递归
        for (int i = pos; i < nums.size(); i++)
        {
            path.push_back(nums[i]);
            dfs(nums, i + 1);
            path.pop_back(); // 恢复现场
        }
    }
};

3、解析

在这里插入图片描述
在这里插入图片描述

三、找出所有子集的异或总和再求和

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

class Solution 
{
public:
    // 1、全局变量
    int sum = 0; // 记录最终结果
    int path = 0; // 记录当前异或后的值
    int subsetXORSum(vector<int>& nums) 
    {
        dfs(nums, 0);
        return sum;
    }
    // 2、递归
    void dfs(vector<int>& nums, int pos)
    {
        // 1、递归出口
        sum += path;
        // 2、往下递归
        for(int i = pos; i < nums.size(); i++)
        {
            path ^= nums[i];
            dfs(nums, i + 1);
            path ^= nums[i];
        }
    }
};

3、解析

在这里插入图片描述

四、全排列II

1、题目解析

leetcode链接

在这里插入图片描述

2、代码

代码1:

class Solution 
{
public:
    // 1、全局变量
    vector<vector<int>> ret; // 记录返回的数组
    vector<int> path; // 记录路径
    bool check[9]; // 判断是否被使用过
    vector<vector<int>> permuteUnique(vector<int>& nums) 
    {
        // 2、排序
        sort(nums.begin(), nums.end());
        // 3、进行递归
        dfs(nums, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos)
    {
        // 1、递归出口
        if(pos == nums.size())
        {
            ret.push_back(path);
            return;
        }
        // 2、每一层的循环
        for(int i = 0; i < nums.size(); i++)
        {
            // 不合法情况进行剪枝
            if(check[i] == true || (i != 0 && nums[i] == nums[i - 1] && check[i - 1] == false))
                continue;
            // path进行增加
            path.push_back(nums[i]);
            check[i] = true;
            // 递归
            dfs(nums, pos + 1);
            // 回溯 -- 恢复现场
            path.pop_back();
            check[i] = false;
        }
    }
};

代码2:

class Solution 
{
public:
    // 1、全局变量
    vector<vector<int>> ret; // 记录返回的数组
    vector<int> path; // 记录路径
    bool check[9]; // 判断是否被使用过
    vector<vector<int>> permuteUnique(vector<int>& nums) 
    {
        // 2、排序
        sort(nums.begin(), nums.end());
        // 3、进行递归
        dfs(nums, 0);
        return ret;
    }
    void dfs(vector<int>& nums, int pos)
    {
        // 1、递归出口
        if(pos == nums.size())
        {
            ret.push_back(path);
            return;
        }
        // 2、每一层的循环
        for(int i = 0; i < nums.size(); i++)
        {
            // 不合法情况进行剪枝
            if(check[i] == false && (i == 0 || nums[i] != nums[i - 1] || check[i - 1] == true))
            {
                // path进行增加
                path.push_back(nums[i]);
                check[i] = true;
                // 递归
                dfs(nums, pos + 1);
                // 回溯 -- 恢复现场
                path.pop_back();
                check[i] = false;
            }
        }
    }
};

3、解析

在这里插入图片描述

五、电话号码的字母组合

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

class Solution 
{
public:
    // 全局变量
    string hash[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    string path; // 记录路径
    vector<string> ret; // 返回的组合
    vector<string> letterCombinations(string digits) 
    {
        if(digits.size() == 0)
            return ret;
        dfs(digits, 0);
        return ret;
    }
    void dfs(string& digits, int pos)
    {
        // 递归出口
        if(digits.size() == pos)
        {
            ret.push_back(path);
            return;
        }
        // 循环找对应关系
        for(auto ch : hash[digits[pos] - '0']) // 掏出来字符串进行遍历当前下标所对应的字符串
        {
            // 尾插进去
            path.push_back(ch);
            dfs(digits, pos + 1);
            path.pop_back(); // 恢复现场
        }
    } 
};

3、解析

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2022horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值