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

这篇具有很好参考价值的文章主要介绍了【leetcode】深搜、暴搜、回溯、剪枝(C++)3。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、解数独

1、题目描述

leetcode链接
【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

2、代码

class Solution 
{
public:
    // 全局变量
    bool row[9][10]; // 行
    bool col[9][10]; // 列
    bool grid[3][3][10]; // 小格子
    void solveSudoku(vector<vector<char>>& board) 
    {
        // 初始化
        for(int i = 0; i < 9; i++)
        {
            for(int j = 0; j < 9; j++)
            {
                if(board[i][j] != '.') // 是数就填进去
                {
                    int num = board[i][j] - '0'; // 记录一下数
                    row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true; // 记录被用过了
                }
            }
        }
        dfs(board);
    }
    bool dfs(vector<vector<char>>& board)
    {
        for(int i = 0; i < 9; i++)
        {
            for(int j = 0; j < 9; j++)
            {
                // 填数
                if(board[i][j] == '.')
                {
                    for(int num = 1; num <= 9; num++) // 从1-9一个个遍历填数
                    {
                        if(!row[i][num] && !col[j][num] && !grid[i / 3][j / 3][num])
                        {
                            board[i][j] = num + '0'; // 填入进去
                            row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true; // 标记用过了
                            if(dfs(board) == true) return true; // 表示可以填进去
                            // 恢复现场
                            board[i][j] = '.';
                            row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = false; // 标记没用
                        }
                    }
                    return false; // 1-9都不行
                }
            }
        }
        return true; // 走完了,填完了,返回true
    }
};

3、解析

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

二、单词搜索

1、题目描述

leetcode链接

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

2、代码

class Solution 
{
public:
    // 全局变量
    bool visit[7][7];
    int m, n;
    bool exist(vector<vector<char>>& board, string word) 
    {
        m = board.size(); // 总共有多少行
        n = board[0].size(); // 一行有多少个
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                // 匹配
                if(word[0] == board[i][j])
                {
                    visit[i][j] = true; // 标记该点已经被访问过了
                    if(dfs(board, i, j, word, 1/*从第一个位置往下走*/)) return true; // 递归到下一层
                    visit[i][j] = false; // 第一个点位置错误,找下一个第一个对应的点
                }
            }
        }
        return false; // 没有访问到
    }
    // 定义一个上下左右移动的向量
    int dx[4] = {0, 0, -1, 1}; // x x x-1 x+1
    int dy[4] = {1, -1, 0, 0}; // y+1 y-1 y y
    bool dfs(vector<vector<char>>& board, int i, int j, string word, int pos)
    {
        // 递归出口
        if(pos == word.size())
        {
            return true;
        }
        for(int k = 0; k < 4; k++)
        {
            int x = dx[k] + i; // x坐标
            int y = dy[k] + j; // y坐标
            // 不越界,当前visit数组未被访问过,当前字符和word相对应字符相同
            if(x >= 0 && x < m && y >=0 && y < n && visit[x][y] == false && word[pos] == board[x][y])
            {
                visit[x][y] = true; // 先定义到访问过
                if(dfs(board, x, y, word, pos + 1)) return true; // 递归下一层
                visit[x][y] = false; // 恢复现场
            }
        }
        return false;
    }
};

3、解析

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

三、黄金矿工

1、题目描述

leetcode链接

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

2、代码

class Solution 
{
public:
    // 全局变量
    bool visit[16][16]; // 标记是否访问过
    int m, n; // m是行,n是列
    int sum; // 总和
    int path; // 每次走的路径
    int getMaximumGold(vector<vector<int>>& grid) 
    {
        m = grid.size();
        n = grid[0].size();
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] != 0) // 先找到第一个非零元素
                {
                    visit[i][j] = true; // 标记一下访问过了
                    path += grid[i][j]; // 路径加上
                    dfs(grid, i, j, path); // 递归
                    visit[i][j] = false; // 找下一个非零元素
                    path -= grid[i][j];
                } 
            }
        }
        return sum;
    }
    int dx[4] = {0, 0, 1, -1}; // 上下左右
    int dy[4] = {1, -1, 0, 0}; // 上下左右
    void dfs(vector<vector<int>>& grid, int i, int j, int path)
    {
        // 递归出口
        sum = max(sum, path); // 这里直接用算法max找最大值

        for(int k = 0; k < 4; k++)
        {
            int x = dx[k] + i; // 向量x
            int y = dy[k] + j; // 向量y
            if(x >= 0 && x < m && y >= 0 && y < n && visit[x][y] == false && grid[x][y] != 0)
            {
                visit[x][y] = true;
                path = path + grid[x][y]; // 路径加上
                dfs(grid, x, y, path);
                visit[x][y] = false; // 恢复现场
                path = path - grid[x][y];
            }
        }
    }
};

3、解析

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

四、不同路径III

1、题目描述

leetcode链接

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法

2、代码

class Solution 
{
public:
    // 全局变量
    int m, n;
    bool visit[21][21]; // 用来记录位置是否被访问过
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int ret; // 统计总路数
    int step; // 记录总共有几个0
    int uniquePathsIII(vector<vector<int>>& grid) 
    {
        m = grid.size(); // 行
        n = grid[0].size(); // 列
        int x = 0; // 记录1的横坐标
        int y = 0; // 记录1的纵坐标
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == 0)
                {
                    step++; // 统计有几个0
                }
                else if(grid[i][j] == 1) // 找到开头
                {
                    x = i;
                    y = j;
                }
            }
        }
        step += 2; // 包含上首尾
        visit[x][y] = true; // 标记一下当前位置被使用过
        dfs(grid, x, y, 1); // 从第一层开始往后递归
        return ret;
    }
    void dfs(vector<vector<int>>& grid, int i, int j, int count/*用来记录每一条路线的0的个数*/)
    {
        // 递归出口
        if(grid[i][j] == 2)
        {
            if(count == step)
            {
                ret++;
            }
            return;
        }
        for(int k = 0; k < 4; k++)
        {
            int x = i + dx[k];
            int y = j + dy[k];
            if(x >= 0 && x < m && y >= 0 && y < n && !visit[x][y] && grid[x][y] != -1)
            {
                visit[x][y] = true;
                dfs(grid, x, y, count + 1);
                visit[x][y] = false;
            }
        }
    }
};

3、解析

【leetcode】深搜、暴搜、回溯、剪枝(C++)3,C++刷题,leetcode,剪枝,c++,算法文章来源地址https://www.toymoban.com/news/detail-835612.html

到了这里,关于【leetcode】深搜、暴搜、回溯、剪枝(C++)3的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 穷举&&深搜&&暴搜&&回溯&&剪枝(3)

    一)字母大小写全排列 784. 字母大小写全排列 - 力扣(LeetCode) 1)从每一个字符开始进行枚举,如果枚举的是一个数字字符,直接忽视 如果是字母的话,进行选择是变还是不变 2)当进行遍历到叶子结点的时候,直接将结果存放到ret里面即可 3)相对于是对于这个决策树做一个深度

    2024年02月14日
    浏览(55)
  • LeetCode刷题13:回溯+剪枝解决216.组合总和 III

    找出所有相加之和为  n   的  k   个数的组合,且满足下列条件: 只使用数字1到9 每个数字  最多使用一次   返回  所有可能的有效组合的列表  。该列表不能包含相同的组合两次,组合可以以任何顺序返回。 示例 1: 输入: k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他

    2024年02月02日
    浏览(44)
  • DFS:深搜+回溯+剪枝解决组合问题

                                                   创作不易,感谢支持!!! . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) 该题和前面是类似的,但是用回溯算法,会超

    2024年04月12日
    浏览(39)
  • DFS:深搜+回溯+剪枝解决排列、子集问题

                                        创作不易,感谢三连支持!!  . - 力扣(LeetCode) . - 力扣(LeetCode)  方案1:不合法就continue 方案2:合法才能进循环 . - 力扣(LeetCode) . - 力扣(LeetCode)  策略1:决策树以选不选作为参考,结果为叶子节点 策略2:决策树以选几个

    2024年04月16日
    浏览(66)
  • DFS:深搜+回溯+剪枝解决矩阵搜索问题

                                                   创作不易,感谢三连!!  . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) 1、矩阵搜索问题经常要用到向量,也就是我们可以通过dx和dy来帮助我们定义方向

    2024年04月17日
    浏览(41)
  • 【算法】递归、回溯、剪枝、dfs 算法题练习(组合、排列、总和问题;C++)

    后面的练习是接着下面链接中的文章所继续的,在对后面的题练习之前,可以先将下面的的文章进行了解👇: 【算法】{画决策树 + dfs + 递归 + 回溯 + 剪枝} 解决排列、子集问题(C++) 思路 题意分析 :要求根据给出的数字,算出合法的括号组成个数。根据题目,我们可以总

    2024年02月22日
    浏览(50)
  • 【leetcode刷题之路】剑指Offer(3)——搜索与回溯算法

    7 搜索与回溯算法 7.1 【BFS】剑指 Offer 32 - I - 从上到下打印二叉树 https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/   这里借助队列来实现广度优先遍历,由于需要访问每一层的节点,而且这一层访问才可以访问下一层,所以可以考虑队列的先进先出,先把每一层的节

    2024年02月13日
    浏览(59)
  • 递归、搜索与回溯算法(专题二:深搜)

    往期文章(希望小伙伴们在看这篇文章之前,看一下往期文章) (1)递归、搜索与回溯算法(专题零:解释回溯算法中涉及到的名词)【回溯算法入门必看】-CSDN博客 (2)递归、搜索与回溯算法(专题一:递归)-CSDN博客  深搜是实现递归的一种方式,接下来我们之间从题

    2024年01月20日
    浏览(81)
  • LeetCode 39. 组合总和(回溯+剪枝)

    链接:LeetCode 39. 组合总和 难度:中等 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选

    2024年02月14日
    浏览(45)
  • 回溯算法例题(剪枝策略)

    链接: 77. 组合 链接: 216. 组合总和 III 链接: 17. 电话号码的字母组合 链接: 39. 组合总和 注:使用剪枝必须对原数组进行排序 链接: 40. 组合总和 II 链接: 131. 分割回文串 链接: 93. 复原 IP 地址 链接: 78. 子集 链接: 90. 子集 II 链接: 46. 全排列 链接: 47. 全排列 II 链接: 51. N 皇后 链接

    2024年02月04日
    浏览(90)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包