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

news2025/3/13 7:56:15

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

  • 一、解数独
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 二、单词搜索
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 三、黄金矿工
    • 1、题目描述
    • 2、代码
    • 3、解析
  • 四、不同路径III
    • 1、题目描述
    • 2、代码
    • 3、解析


一、解数独

1、题目描述

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

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、解析

在这里插入图片描述

二、单词搜索

1、题目描述

leetcode链接

在这里插入图片描述

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、解析

在这里插入图片描述

三、黄金矿工

1、题目描述

leetcode链接

在这里插入图片描述

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、解析

在这里插入图片描述

四、不同路径III

1、题目描述

leetcode链接

在这里插入图片描述

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、解析

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1453713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BIG DATA —— 大数据时代

大数据时代 [英] 维克托 迈尔 — 舍恩伯格 肯尼斯 库克耶 ◎ 著 盛杨燕 周涛◎译 《大数据时代》是国外大数据研究的先河之作&#xff0c;本书作者维克托迈尔舍恩伯格被誉为“大数据商业应用第一人”&#xff0c;他在书中前瞻性地指出&#xff0c;大数据带来的信息…

微服务—DSL基础语法与RestClient操作

本博客为个人学习笔记&#xff0c;学习网站&#xff1a;黑马程序员SpringCloud 2021教程 目录 DSL语法 索引库操作 mapping属性 创建索引库 字段拷贝 查询、删除、修改索引库 文档操作 新增文档 查询、删除文档 修改文档 全量修改 增量修改 DSL文档语法小结 Rest…

Mac配置Python3最简单的方法

此文介绍Mac用Anaconda配置Python3 达成效果 能让你目前只装有Python2的Mac装上Python3&#xff0c;同时拥有很多科学计算库 anaconda介绍 anaconda 是一个python的发行版&#xff0c;包括了python和很多常见的软件库, 和一个包管理器conda。常见的科学计算类的库都包含在里…

美国突然致敬中本聪

作者&#xff1a;秦晋 有点看不懂美国的神操作。 2月16日&#xff0c;据《Bitcoin Magazine》报道&#xff0c;比特币的竞争对手、美国参议员伊丽莎白-沃伦对比特币的立场突然180度大转弯。由反对立场转为支持立场。让很多行业媒体出乎意料&#xff0c;甚至惊掉下巴。 报道称&a…

【测试】JUnit

目 录 一.注解二.断言三.用例的执行顺序四.参数化五.测试套件 自动化就是 selenium 脚本来实现的 junit 是 java 的单亓测试工具&#xff0c;只不过我们在实现自动化的时候需要借用一下下 junit 库里面提供的一些方法 引入依赖 Junit 5 <!-- https://mvnrepository.com/a…

php 数组函数

php 数组函数 1. 常用的php数组函数 1. 常用的php数组函数 array_pop() 删除数组中最后一个元素 array_push() 将一个或多个元素插入到数组的末尾 array_keys <?php $arr array("刘岩" > 30, "范冰冰" > 31, "娜扎" > 31);$…

DS:八大排序之堆排序、冒泡排序、快速排序

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01; 一、堆排序 堆排序已经在博主关于堆的实现过程中详细的讲过了&#xff0c;大家可以直接去看&#xff0c;很详细,这边不介绍了 DS&#xff1a;二叉树的顺序结构及堆的实现-CSDN博客 直接上代码&#xff1a; …

备战蓝桥杯---图论之最小生成树

首先&#xff0c;什么是最小生成树&#xff1f; 他就是无向图G中的所有生成树中树枝权值总和最小的。 如何求&#xff1f; 我们不妨采用以下的贪心策略&#xff1a; Prim算法&#xff08;复杂度&#xff1a;&#xff08;nm)logm)&#xff1a; 我们对于把上述的点看成两个集…

MAC VSCODE g++编译器无法编译C++11语法的 解决办法(CodeRunner版本)

如果你是使用的 codeRunner 这个插件&#xff0c;就是这个按钮 coderunner的原理大致是&#xff1a;先判断你这是什么语言&#xff0c;然后有一个 code-runner.executorMap 来对应各个语言是用什么执行语句 我发现&#xff0c;我修改之前&#xff08;无法执行C11语法的原因是&a…

智能汽车专题:智能驾驶2023年度报告

今天分享的是智能汽车系列深度研究报告&#xff1a;《智能汽车专题&#xff1a;智能驾驶2023年度报告》。 &#xff08;报告出品方&#xff1a;量子位智库&#xff09; 报告共计&#xff1a;30页 来源&#xff1a;人工智能学派 顶天立地&#xff1a;技术进阶路线明晰 根据…

echarts制作两个柱状图

let colorList[#02ce8b,#ffbe62,#f17373]; let data1 [90,80,70,50] option { title:[{ // 第一个标题text: 环保检测, // 主标题textStyle: { // 主标题样式color: #333,fontWeight: bold,fontSize: 16},left: 20%, // 定位到适合的位置top: 10%, // 定位到适合的位置},{ //…

小程序获取手机号:快速验证和实时验证

概述 小程序手机号快速验证和实时验证都已经开始收费了。 手机号实时验证组件&#xff0c;在每次请求时&#xff0c;平台均会对用户选择的手机号进行实时验证&#xff1b;每次组件调用成功&#xff0c;收费0.04元手机号快速验证组件&#xff0c;平台会对号码进行验证&#xf…

论文阅读_语音识别_Wisper

英文名称: Robust Speech Recognition via Large-Scale Weak Supervision 中文名称: 通过大规模弱监督实现鲁棒语音识别 链接: https://proceedings.mlr.press/v202/radford23a.html 代码: https://github.com/openai/whisper 作者: Alec Radford, Jong Wook Kim, Tao Xu, Greg…

基于协同过滤的时尚穿搭推荐系统

项目&#xff1a;基于协同过滤的时尚穿搭推荐系统 摘 要 基于协同过滤的时尚穿搭推荐系统是一种能自动从网络上收集信息的工具&#xff0c;可根据用户的需求定向采集特定数据信息的工具&#xff0c;本项目通过研究服饰流行的分析和预测的分析和预测信息可视化时尚穿搭推荐系统…

2024免费人像摄影后期处理工具Portraiture4.1

Portraiture作为一款智能磨皮插件&#xff0c;确实为Photoshop和Lightroom用户带来了极大的便利。通过其先进的人工智能算法&#xff0c;它能够自动识别并处理照片中的人物皮肤、头发和眉毛等部位&#xff0c;实现一键式的磨皮美化效果&#xff0c;极大地简化了后期处理的过程。…

STM32下载后需要复位

下载后需要复位才能自动运行程序&#xff0c;需要以下两步 STEP1 STEP2 一个勾选&#xff0c;一个不勾选。

乡政府|乡政府管理系统|基于Springboot的乡政府管理系统设计与实现(源码+数据库+文档)

乡政府管理系统目录 目录 基于Springboot的乡政府管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、活动信息管理 3、新闻类型管理 4、新闻动态管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

内存块与内存池

&#xff08;1&#xff09;在运行过程中&#xff0c;MemoryPool内存池可能会有多个用来满足内存申请请求的内存块&#xff0c;这些内存块是从进程堆中开辟的一个较大的连续内存区域&#xff0c;它由一个MemoryBlock结构体和多个可供分配的内存单元组成&#xff0c;所有内存块组…

JAVA之Java线程核心详解

Java线程核心 1.进程和线程 进程&#xff1a;进程的本质是一个正在执行的程序&#xff0c;程序运行时系统会创建一个进程&#xff0c;并且给每个进程分配独立的内存地址空间保证每个进程地址不会相互干扰。同时&#xff0c;在 CPU 对进程做时间片的切换时&#xff0c;保证进程…

Java 抽象容器类源码剖析

总体介绍 抽象容器类接口和具体容器类的关系如图所示&#xff0c;顶层包括Collection、List、Set、Queue、Deque和Map6个抽象容器类。 AbstractCollection&#xff1a;实现了Collection接口&#xff0c;被抽象类AbstractList、AbstractSet、AbstractQueue继承&#xff0c;Arra…