【递归与回溯深度解析:经典题解精讲(下篇)】—— Leetcode

文章目录

  • 有效的数独
  • 解数独
  • 单词搜索
  • 黄金矿工
  • 不同的路径|||

有效的数独

在这里插入图片描述
递归解法思路

  • 将每个数独的格子视为一个任务,依次检查每个格子是否合法。
    如果当前格子中的数字违反了数独规则(在行、列或 3×3 小方块中重复),直接返回 False。
    递归检查下一个格子,直到所有格子都检查完毕。
    如果所有格子都合法,则返回 True。
class Solution 
{// 使用三个布尔数组分别记录数独中行、列和3x3小方块中是否已经存在某个数字。bool row[9][10];    // row[i][num] 表示第 i 行是否已经存在数字 numbool col[9][10];    // col[j][num] 表示第 j 列是否已经存在数字 numbool grid[3][3][10]; // grid[i][j][num] 表示第 (i, j) 个 3x3 小方块中是否已经存在数字 num
public:bool isValidSudoku(vector<vector<char>>& board) {// 遍历整个 9x9 的棋盘for(int i = 0; i < 9; i++) // 遍历每一行{for(int j = 0; j < 9; j++) // 遍历每一列{// 如果当前格子不为空(即不是 '.')if(board[i][j] != '.'){int num = board[i][j] - '0'; // 将字符数字转换为整数// 检查当前数字 num 是否已经在当前行、列或 3x3 小方块中存在if(row[i][num] || col[j][num] || grid[i / 3][j / 3][num])return false; // 如果存在,说明数独无效,返回 false// 如果没有冲突,则将 num 标记为已存在row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;}}}// 如果遍历结束没有发现冲突,说明数独有效,返回 truereturn true;}
};

解数独

在这里插入图片描述
思路:回溯算法

  • 使用回溯法填充数独的空格。
    对于每个空格,尝试填入数字 1-9,并检查当前数字是否满足数独规则:
    当前数字在行中是否唯一。
    当前数字在列中是否唯一。
    当前数字在 3×3 小方块中是否唯一。
    如果满足规则,则递归求解下一个空格;如果不满足,则回溯到上一步继续尝试。
    当所有空格都填满且数独有效时,返回结果。
class Solution 
{// 使用三个布尔数组记录数独中行、列和3x3小方块中是否已经存在某个数字bool col[9][10];    // col[j][num] 表示第 j 列是否已经存在数字 numbool row[9][10];    // row[i][num] 表示第 i 行是否已经存在数字 numbool grid[3][3][10]; // grid[i][j][num] 表示第 (i, j) 个 3x3 小方块中是否已经存在数字 numpublic:// 主函数:解数独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] == '.') // 找到空格子{// 尝试填入数字 1 到 9for(int num = 1; num <= 9; num++){// 如果当前数字 num 在对应的行、列和小方块中都未出现if(!row[i][num] && !col[j][num] && !grid[i / 3][j / 3][num]){// 填入数字board[i][j] = '0' + num; // 将整数转换为字符// 标记当前数字在行、列和小方块中已存在row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = true;// 递归求解下一步if(dfs(board) == true) return true;// 如果递归返回 false,说明当前解不正确,需要回溯board[i][j] = '.'; // 恢复空格子row[i][num] = col[j][num] = grid[i / 3][j / 3][num] = false; // 取消标记}}// 如果 1-9 都无法填入,返回 falsereturn false;}}}// 如果遍历完所有格子都有效,返回 truereturn true;}
};

单词搜索

在这里插入图片描述
思路:回溯+深度优先搜索 (DFS)

  • 问题是查找网格中是否存在给定单词。
    遍历网格中的每个字符作为起点,使用回溯和 DFS 搜索路径:
    如果当前字符匹配单词的第一个字符,则继续递归搜索四个方向(上下左右)。
    使用标志位(例如临时修改字符)避免重复访问。
    如果路径不符合要求,则回溯到上一层。
    如果成功找到完整路径,则返回 true;否则继续尝试其他起点。
class Solution 
{bool vis[7][7]; // 标记每个网格点是否已被访问,避免重复使用int m, n;       // 网格的行数 (m) 和列数 (n)public:// 主函数,判断单词是否存在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(board[i][j] == word[0]){vis[i][j] = true; // 标记当前格子为已访问// 从当前格子开始深度优先搜索if(dfs(board, i, j, word, 1)) return true;vis[i][j] = false; // 回溯时取消标记}}}return false; // 如果所有起点都不能找到完整单词,则返回 false}// 方向数组,用于表示上下左右的移动int dx[4] = {0, 0, -1, 1}; // 水平方向int dy[4] = {-1, 1, 0, 0}; // 垂直方向// 深度优先搜索函数bool dfs(vector<vector<char>>& board, int i, int j, string& word, int pos){// 递归终止条件:如果已经匹配到单词的最后一个字符,返回 trueif(pos == word.size())return true;// 遍历当前格子的四个方向for(int k = 0; k < 4; k++){int x = i + dx[k]; // 新的行坐标int y = j + dy[k]; // 新的列坐标// 判断新位置是否合法且匹配当前单词字符if(x >= 0 && y >= 0 && x < m && y < n && !vis[x][y] && board[x][y] == word[pos]){vis[x][y] = true; // 标记新位置为已访问// 递归继续搜索下一个字符if(dfs(board, x, y, word, pos + 1)) return true;vis[x][y] = false; // 回溯时取消标记}}return false; // 如果四个方向都找不到匹配路径,返回 false}
};

黄金矿工

在这里插入图片描述
思路:回溯+深度优先搜索 (DFS)

  • 在网格中寻找一条路径,使得采集的黄金总量最大,路径可以在上下左右四个方向移动,但不能重复访问。
    遍历网格中的每个点作为起点,使用回溯和 DFS 搜索:
    当前点的黄金加入总和。
    标记当前点已访问,递归搜索四个方向。
    搜索完成后,恢复当前点状态(回溯)。
    返回所有路径中黄金总和的最大值。
class Solution 
{bool vis[16][16]; // 标记网格中的格子是否已被访问int m, n;         // 网格的行数 (m) 和列数 (n)int dx[4] = {0, 0, -1, 1}; // 表示移动的水平方向:左右int dy[4] = {-1, 1, 0, 0}; // 表示移动的垂直方向:上下int ret; // 记录黄金路径的最大总量public:// 主函数,返回可以采集的最大黄金总量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]) // 如果当前格子有黄金{vis[i][j] = true; // 标记当前格子为已访问dfs(grid, i, j, grid[i][j]); // 从当前格子开始深度优先搜索vis[i][j] = false; // 回溯时恢复状态}}}return ret; // 返回找到的最大黄金总量}// 深度优先搜索函数void dfs(vector<vector<int>>& grid, int i, int j, int path){ret = max(ret, path); // 更新最大黄金总量// 遍历四个方向for(int k = 0; k < 4; k++){int x = i + dx[k]; // 计算新的行坐标int y = j + dy[k]; // 计算新的列坐标// 判断新坐标是否合法、是否未访问以及是否有黄金if(x >= 0 && y >= 0 && x < m && y < n && !vis[x][y] && grid[x][y]){vis[x][y] = true; // 标记新位置为已访问dfs(grid, x, y, grid[x][y] + path); // 递归搜索vis[x][y] = false; // 回溯时恢复状态}}}
};

不同的路径|||

在这里插入图片描述
思路:回溯+深度优先搜索 (DFS)

  • 在网格中寻找一条路径,要求:
    从起点走到终点。
    必须经过所有空格,不能遗漏也不能重复。
    使用回溯法遍历网格:
    遍历网格找到起点,并统计需要经过的空格数量。
    从起点出发,递归搜索四个方向:
    标记当前点已访问。
    如果到达终点且已访问所有空格,路径计数+1。
    搜索完成后,恢复当前点状态(回溯)。
    返回所有满足条件的路径总数。
class Solution 
{int m, n, step; // m 和 n 是网格的行列大小,step 是需要经过的格子总数bool vis[21][21]; // 标记网格中的格子是否已被访问,避免重复访问int dx[4] = {0, 0, -1, 1}; // 表示水平方向的移动(左右)int dy[4] = {-1, 1, 0, 0}; // 表示垂直方向的移动(上下)int ret; // 记录所有满足条件的路径数public:// 主函数:返回所有满足条件的路径数int uniquePathsIII(vector<vector<int>>& grid) {m = grid.size();  // 获取网格的行数n = grid[0].size(); // 获取网格的列数int bx = 0, by = 0; // 起点坐标// 遍历网格,初始化起点和统计需要经过的格子总数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)   // 找到起点{bx = i;by = j;}}}step += 2; // 包括起点和终点在内,总共需要经过的格子数// 从起点开始进行 DFSvis[bx][by] = true; // 标记起点为已访问dfs(grid, bx, by, 1); // 起点已访问,计数为 1return ret; // 返回有效路径的数量}// 深度优先搜索函数void dfs(vector<vector<int>>& grid, int i, int j, int count){// 如果当前格子是终点(值为 2)if(grid[i][j] == 2){// 如果路径经过了所有需要访问的格子if(count == step)ret++; // 计数器加 1return;}// 遍历当前格子的四个方向for(int k = 0; k < 4; k++){int x = i + dx[k]; // 新的行坐标int y = j + dy[k]; // 新的列坐标// 判断新位置是否合法if(x >= 0 && y >= 0 && x < m && y < n && grid[x][y] != -1 && !vis[x][y]){vis[x][y] = true; // 标记新位置为已访问dfs(grid, x, y, count + 1); // 递归搜索下一步vis[x][y] = false; // 回溯时恢复状态}}}
};

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

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

相关文章

Llama 3 预训练(二)

目录 3. 预训练 3.1 预训练数据 3.1.1 网络数据筛选 PII 和安全过滤 文本提取与清理 去重&#xff08;De-duplication&#xff09; 启发式过滤&#xff08;Heuristic Filtering&#xff09; 基于模型的质量过滤 代码和数学推理数据处理 多语言数据处理 3.1.2 确定数…

双指针——查找总价格为目标值的两个商品

一.题目描述 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 二.题目解析 这个题目非常简单&#xff0c;其实就是判断有没有两个数加起来等于target。 三.算法解析 1.暴力解法 暴力解法的话我们可以枚举出所有的情况&#xff0c;然后判…

sqlserver镜像设置

本案例是双机热备&#xff0c;只设置主体服务器&#xff08;主&#xff09;和镜像服务器&#xff08;从&#xff09;&#xff0c;不设置见证服务器 设置镜像前先检查是否启用了 主从服务器数据库的 TCP/IP协议 和 RemoteDAC &#xff08;1&#xff09;打开SQL Server配置管理器…

Elasticsearch:analyzer(分析器)

一、概述 可用于将字符串字段转换为单独的术语&#xff1a; 添加到倒排索引中&#xff0c;以便文档可搜索。级查询&#xff08;如 生成搜索词的 match查询&#xff09;使用。 分析器分为内置分析器和自定义的分析器&#xff0c;它们都是由若干个字符过滤器&#xff08;chara…

ElementPlus 自定义封装 el-date-picker 的快捷功能

文章目录 需求分析 需求 分析 我们看到官网上给出的案例如下&#xff0c;但是不太满足我们用户想要的快捷功能&#xff0c;因为不太多&#xff0c;因此需要我们自己封装一些&#xff0c;方法如下 外部自定义该组件的快捷内容 export const getPickerOptions () > {cons…

低代码开发平台排名2024

低代码开发平台在过去几年中迅速崛起&#xff0c;成为企业数字化转型的重要工具。这些平台通过可视化界面和拖放组件&#xff0c;使业务人员和技术人员都能快速构建应用程序&#xff0c;大大缩短了开发周期。以下是一些在2024年值得关注和使用的低代码开发平台。 一、Zoho Cre…

计算机网络——期末复习(4)协议或技术汇总、思维导图

思维导图 协议与技术 物理层通信协议&#xff1a;曼彻斯特编码链路层通信协议&#xff1a;CSMA/CD &#xff08;1&#xff09;停止-等待协议&#xff08;属于自动请求重传ARQ协议&#xff09;&#xff1a;确认、否认、重传、超时重传、 &#xff08;2&#xff09;回退N帧协…

【MySQL学习笔记】关于索引

文章目录 【MySQL学习笔记】关于索引1.索引数据结构2.索引存储3.联合索引3.1 联合索引的b树结构3.2 索引覆盖&#xff1f;回表&#xff1f;3.3 联合索引最左匹配原则3.5 索引下推 4.索引失效 【MySQL学习笔记】关于索引 1.索引数据结构 索引是一种能提高查询速度的数据结构。…

D104【python 接口自动化学习】- pytest进阶参数化用法

day104 pytest参数化parametrize单参数 学习日期&#xff1a;20241223 学习目标&#xff1a;pytest基础用法 -- pytest参数化parametrize单参数 学习笔记&#xff1a; 参数化 parametrize 参数化可以组装测试数据&#xff0c;在测试前定义好测试数据&#xff0c;并在测试用…

第T4周:TensorFlow实现猴痘识别(Tensorboard的使用)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目标&#xff1a; 1、学习tensorboard的使用 具体实现&#xff1a; &#xff08;一&#xff09;环境&#xff1a; 语言环境&#xff1a;Python 3.10 编 译 器…

Docker-构建自己的Web-Linux系统-镜像webtop:ubuntu-kde

介绍 安装自己的linux-server,可以作为学习使用&#xff0c;web方式访问&#xff0c;基于ubuntu构建开源项目 https://github.com/linuxserver/docker-webtop安装 docker run -d -p 1336:3000 -e PASSWORD123456 --name webtop lscr.io/linuxserver/webtop:ubuntu-kde登录 …

小米路由器开启SSH,配置阿里云ddns,开启外网访问SSH和WEB管理界面

文章目录 前言一、开启SSH二、配置阿里云ddns1.准备工作2.创建ddns脚本3.添加定时任务 三、开启外网访问SSH和WEB管理界面1、解除WEB管理页面访问限制2.手动添加防火墙端口转发规则&#xff0c;开启外网访问WEB管理和SSH 前言 例如&#xff1a;随着人工智能的不断发展&#xf…

什么是ESC ---- 防止车辆打滑并提高驾驶时稳定性的技术

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所谓鸡汤&#xff0c;要么蛊惑你认命&#xff0c;要么怂恿你拼命&#xff0c;但都是回避问题的根源&…

LinkedList类 (链表)

目录 一. LinkedList 基本介绍 二. LinkedList 中的法及其应用 1. 添加元素 (1) add() (2) addAll() (3) addFirst() (4) addLast() 2. 删除元素 (1) remove() (2) removeAll() (3) removeFirst() (4) removeLast() 3. 遍历元素 (1) for 循环遍历 (2) for - each …

复习打卡大数据篇——Hadoop MapReduce

目录 1. MapReduce基本介绍 2. MapReduce原理 1. MapReduce基本介绍 什么是MapReduce MapReduce是一个分布式运算程序的编程框架&#xff0c;核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在Hadoop集群上。 MapRed…

Java基础知识(四) -- 面向对象(下)

1.类变量和类方法 1.1 类变量背景 有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人在玩? 思路分析: 核心在于如何让变量count被所有对象共享 public class Child {private String name;// 定义静态变量(所有Child对象共享)public static int count 0;p…

SpringBoot中使用TraceId进行日志追踪

**查询日志的痛点&#xff1a;**项目中每当我们查询日志的时候都是看前端请求什么接口&#xff0c;根据一些关键字进入服务器查询日志中是否有这个关键字&#xff0c;然而这个关键字在日志里面并不是唯一的&#xff0c;所以要生成一个唯一的标识&#xff0c;每一次请求都是唯一…

C++类与对象上

1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题 例如洗衣服&#xff1a; C是基于面向对象的&#xff0c;关注的是对象&#xff0c;讲一件事拆分成不同的对象&#xff0c;靠对…

向量组学习

向量组的秩及其线性组合 线性相关性 先看a1,a2 如果这两个向量不对应成比例的话,那必然内部不可能存在多余的向量,也就是无关. 主元所在的列都是独立向量 ,最大无关组就是b1,b2,b4,但这个是初等行变换后的,题目要的是A的,与之对应的就是a1,a2,a4 方程组解的结构

使用VS Code开发ThinkPHP项目

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《ThinkPHP 8高效构建Web应用 夏磊 编程与应用开发丛书 清华大学出版社》【摘要 书评 试读】- 京东图书 ThinkPHP 8开发环境安装-CSDN博客 安装ThinkPHP项目的IDE 常用的集成开发环境&#xff08;IDE&#xff09;包括P…