0125 搜索与回溯算法 Day14

news2024/11/25 7:23:31

剑指 Offer 12. 矩阵中的路径

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:

输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false

class Solution {
    public boolean exist(char[][] board, String word) {

    }
}

解题思路

典型的矩阵搜索问题,可使用 深度优先搜索(DFS)+ 剪枝 解决。

深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。


剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为 可行性剪枝 。

递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k 。


终止条件:
返回 false :

(1) 行或列索引越界

(2) 当前矩阵元素与目标字符不同

(3) 当前矩阵元素已访问过 ( (3) 可合并至 (2) ) 。
返回 true :

k = len(word) - 1 ,即字符串 word 已全部匹配。


递推工作:
标记当前矩阵元素: 将 board[i][j] 修改为 空字符 '' ,代表此元素已访问过,防止之后搜索时重复访问。
搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果至 res 。
还原当前矩阵元素: 将 board[i][j] 元素还原至初始值,即 word[k] 。
返回值: 返回布尔量 res ,代表是否搜索到目标字符串。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

代码如下

class Solution {
    public boolean exist(char[][] board, String word) {
        char[] words = word.toCharArray();
        for(int i = 0; i < board.length; i++) {
            for(int j = 0; j < board[0].length; j++) {
                if(dfs(board, words, i, j, 0)) return true;
            }
        }
        return false;
    }
    boolean dfs(char[][] board, char[] word, int i, int j, int k) {
        if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[k]) return false;
        if(k == word.length - 1) return true;
        board[i][j] = '\0';
        boolean res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) || 
                      dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
        board[i][j] = word[k];
        return res;
    }
}

使用'\0'做标记:防止标记字符与矩阵原有字符重复。当存在重复时,此算法会将矩阵原有字符认作标记字符,从而出现错误。 


剑指 Offer 13. 机器人的运动范围 

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

示例 1:

输入:m = 2, n = 3, k = 1
输出:3


示例 2:

输入:m = 3, n = 1, k = 0
输出:1

class Solution {
    public int movingCount(int m, int n, int k) {

    }
}

解题思路

通过循环求得数位和 s

int sums(int x)
    int s = 0;
    while(x != 0) {
        s += x % 10;
        x = x / 10;
    }
    return s;

由于机器人每次只能移动一格(即只能从 x 运动至 x±1),因此每次只需计算 x 到 x±1 的数位和增量

当 (x + 1) % 10 = 0 时,s_x + 1 = s_x - 8 ,例如19,20的数位和分别为 10 和 2

(x + 1) % 10 != 0 ? s_x + 1 : s_x - 8;

可达解分析:
根据数位和增量公式得知,数位和每逢 进位 突变一次。根据此特点,矩阵中 满足数位和的解 构成的几何形状形如多个 等腰直角三角形 ,每个三角形的直角顶点位于 0, 10, 20, ...0,10,20,... 等数位和突变的矩阵索引处 。

三角形内的解虽然都满足数位和要求,但由于机器人每步只能走一个单元格,而三角形间不一定是连通的,因此机器人不一定能到达,称之为 不可达解 ;同理,可到达的解称为 可达解 (本题求此解) 。

 

 

 

 

 

算法解析:
递归参数: 当前元素在矩阵中的行列索引 i 和 j ,两者的数位和 si, sj 。


终止条件:

 ① 行列索引越界

② 数位和超出目标值 k

③ 当前元素已访问过 时,返回 0 ,代表不计入可达解。


递推工作:
标记当前单元格 :将索引 (i, j) 存入 visited 中,代表此单元格已被访问过。
搜索下一单元格: 计算当前元素的 下、右 两个方向元素的数位和,并开启下层递归 。
回溯返回值: 返回 1 + 右方搜索的可达解总数 + 下方搜索的可达解总数,代表从本单元格递归搜索的可达解总数。

 

 

 

 

 

 

 

 

 

 

 

 

代码如下

class Solution {
    int m, n, k;
    boolean[][] visited;
    public int movingCount(int m, int n, int k) {
        this.m = m; this.n = n; this.k = k;
        this.visited = new boolean[m][n];
        return dfs(0, 0, 0, 0);
    }
    public int dfs(int i, int j, int si, int sj) {
        if(i >= m || j >= n || k < si + sj || visited[i][j]) return 0;
        visited[i][j] = true;
        return 1 + dfs(i + 1, j, (i + 1) % 10 != 0 ? si + 1 : si - 8, sj) + dfs(i, j + 1, si, (j + 1) % 10 != 0 ? sj + 1 : sj - 8);
    }
}

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

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

相关文章

GLAD:带有反射壁的空心波导

概述 离散傅里叶变换的混叠效应为带有反射壁的空心波导的建模提供了一个便捷的方法。反射壁可以将光返回到光路中而混叠效应将使溢出光场从反方向折回到采样光场中。如果光场分布是一个偶函数&#xff0c;那么折回的作用就如同反射效果。我们可以将任意形状的光场分布转化成…

推荐一款免费的AI绘图软件,可生成二次元画作和3D模型

随着AI绘画的火热&#xff0c;市面上关于AI绘画的话题居高不小&#xff0c;各种教程、软件、小程序也是满天飞&#xff0c;在这些眼花缭乱的推荐中&#xff0c;究竟哪一款ai绘图软件才是真正适合自己的&#xff0c;不但免费&#xff0c;生成出来的二次元画作还很精美&#xff1…

早教资源网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 网站前台&#xff1a;关于我们、联系我们、公告信息、二手物品、资源信息 管理员功能&#xff1a; 1、管理关于我们、联…

Django 第三天学习笔记

1.模板层-变量和标签 能够传递到Django模板中的数据类型&#xff1a; 1.str 字符串 2.Int 整形 3.List 数组 4.Tuple 元组 5.Dict 字典 6.Func 方法 7.Obj 类的实例化对象。 在模板中使用的变量的语法&#xff1a; {{变量名}}{{变量名.index}} #索引{{变量名.key}} #获取字典对…

数据结构顺序栈

栈 这是大话数据结构种对于栈的描述 可以看到 栈是一种特殊的线性表 它只能在尾部进行元素的插入和删除 但是在栈种 这叫做 入栈 和 出栈 而且它遵循 先进入的元素后出 后进入的元素先出 即就是我们常听说的 先进后出 和后进先出 这里就有一个简单的例子 先进后出 后进先出…

【Node.js】实现微信小程序在线支付功能

实战项目名称&#xff1a;微信小程序实现在线支付功能 - 文章结尾附上微信小程序码&#xff0c;扫码登录后即可体验&#xff01;&#xff01; 文章目录一、实战步骤1. 前期准备2. 添加wechatpay-node-v3和fs插件3. 预设微信下单的数据4. 将上一步骤的下单信息返回给前端5. 小程…

在抖音全程看世界杯,超高清直播背后的硬实力

导语&#xff1a;IT技术赛场开赛&#xff01;作者 | 宋慧 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;当前&#xff0c;2022 卡塔尔世界杯比赛正在如火如荼进行中&#xff0c;处在更加激烈关键的半决赛阶段。作为足球运动的全球顶级赛事&#xff0c;世界杯…

SysML图例-核聚变

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> [新闻]核聚变里程碑式突破>> SysML图中词汇&#xff1a; Tokamak&#xff1a; 一种利用磁约束来实现受控核聚变的环形容器&#xff0c;通过约束电磁波驱动&#xff…

如何形成前端知识体系

来啦各位大佬&#xff5e;但很不好意思&#xff0c;我就是标题党&#xff0c;这篇博文并没有很明确的给出「如何形成前端知识体系」答案&#xff0c;我自学前端&#xff0c;在面试字节的时候&#xff0c;字节的大佬说我的知识点没有成体系&#xff0c;很零散的飘在各个地方&…

面试官:你如何实现大文件上传

提到大文件上传&#xff0c;在脑海里最先想到的应该就是将图片保存在自己的服务器&#xff08;如七牛云服务器&#xff09;&#xff0c;保存在数据库&#xff0c;不仅可以当做地址使用&#xff0c;还可以当做资源使用&#xff1b;或者将图片转换成base64&#xff0c;转换成buff…

怎么复制网页上不能复制的文字(付费文档免费复制),一招搞定

好多小伙伴上网查资料的时候&#xff0c;想要复制网页内容&#xff0c;但是提示付费复制或者不允许复制&#xff0c;遇到这种情况怎么办呢&#xff1f;下面就是小编分享的一招搞定无法复制网页内容文字的方法。 怎么复制网页上不能复制的文字 借助360安全浏览器/360极速浏览器…

Minecraft 1.19.2 Forge模组开发 06.建筑生成

1.12.2自定义建筑生成 1.16.5自定义建筑生成 1.18.2自定义建筑生成 我们本次尝试在主世界生成一个自定义的建筑。 效果展示效果展示效果展示 由于版本更新缘故&#xff0c;1.19的建筑生成将不涉及任何Java包的代码编写&#xff0c;只需要在数据包中对建筑生成进行自定义。 …

基于粒子群优化算法的BP神经网络预测模型(Matlab代码实现)

目录 1 概述 2 粒子群优化算法 3 BP神经网络 4 PSO优化 BP网络算法 5 运行结果 6 参考文献 7 Matlab代码实现 1 概述 在工程应用中经常会遇到一些复杂的非线性系统,这些系统的状态方程复杂,难以准确的用数学方法建模,而BP神经网络实质上实现了一个从输入到输出的映射功…

【k8s】Kubernetes 基础组件详解

一、k8s简介 Kubernetes 是容器集群管理系统工具&#xff0c;是一个开源平台&#xff0c;可实现容器集群的自动化部署、自动扩缩容、维护等功能。Kubernetesk8s是Kubernetes的缩写&#xff0c;Google 于 2014 年开源了 Kubernetes 项目&#xff0c;Kubernetes的名字来自希腊语&…

无延时直播/超低延时直播实际测试延时效果(项目实测组图)

阿酷TONY / 2022-11-30 / 长沙 / 超多组图 无延时直播/超低延时直播&#xff0c;主要只测试延时情况&#xff0c;没有涉及直播产品的功能、使用操作界面&#xff0c;有兴趣的朋友可以加联系我实际测试哦~~~ 1.无延时直播应用场景 无延时直播/超低延时常见应用场景&#…

近90天互动量破百万,「围炉煮茶」究竟做对了什么?

今年秋冬&#xff0c;“围炉煮茶”爆红网络。小红书相关笔记数量突破8万&#xff0c;累计话题浏览量1200万次&#xff0c;近90天互动量破百万&#xff01; 茶&#xff0c;从老一辈的茶杯茶盘里&#xff0c;通过创新再造&#xff0c;成为年轻人的社交“新”头好。高流量曝光、高…

Go语言性能剖析利器--pprof实战

作者&#xff1a;耿宗杰 前言 关于pprof的文章在网上已是汗牛充栋&#xff0c;却是千篇一律的命令介绍&#xff0c;鲜有真正实操的&#xff0c;本文将参考Go社区资料&#xff0c;结合自己的经验&#xff0c;实战Go程序的性能分析与优化过程。 优化思路 首先说一下性能优化的…

什么是文档管理?

什么是文档管理&#xff1f; 文档管理是指在公司或组织内部组织、存储和检索文档以及自动化工作流程所需的流程和资源。文档可以是硬拷贝或数字格式&#xff0c;包括合同、表单、发票、工作申请、福利登记信息和其他记录。 强大的文档管理的重要性 平均而言&#xff0c;由于…

Web实时预览 界面组件Telerik——提高开发者工作效率的完美组合

Telerik DevCraft包含一个完整的产品栈来构建您下一个Web、移动和桌面应用程序。它使用HTML和每个.NET平台的UI库&#xff0c;加快开发速度。Telerik DevCraft提供最完整的工具箱&#xff0c;用于构建现代和面向未来的业务应用程序。 Telerik ASP.NET AJAX (Web Forms) 组件在…

SAP ABAP OAOR SBDSV1新建BDS类/DOI大数据量输出EXCEL时错误空白或不完整

SAP ABAP OAOR SBDSV1新建BDS类/ DOI大数据量输出 EXCEL时错误空白或不完整 引言&#xff1a; 今日回顾 DOI 使用过程中的两个问题&#xff0c;第一个是管理性问题&#xff08;新建 BDS 类&#xff09;&#xff0c;第二个是技术性问题&#xff08; DOI 大数据量输出 EXCEL 时错…