LeetCode 79 单词搜索 | 解题思路分享

news2024/11/23 1:00:59

原题链接:79. 单词搜索

题目难度:中等

题目描述

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

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

示例 1:

img

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

示例 2:

img

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:

img

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • boardword 仅由大小写英文字母组成

进阶:你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?


解题思路

这道题可以用深度优先搜索来解,题目的意思是行走过程中拼成的单词要等于题目给出的单词,然后让我们找一条这样的行走路径。

可以这样去转化:

  • 起点仍然是固定的,就是在网格中与单词第一个字母相同的格子,可能有多个起点,可以通过遍历网格找到。
  • 从起点往四周去寻找,哪个方向能走取决于网格的内容是否与单词的字母相同,但同一个格子不能走两次。

这其实就很容易看出来了,就是一道迷宫题,深度优先搜索就可以应对。

假设我们现在从起点(记为x , y)出发,当前要找的内容为单词的第一个字母(第几个记为index),那么具体思路:

  1. 设置递归的终止条件(按序号判断)

    1. 如果当前格子的值不等于单词的第一个字母,那肯定没戏了,直接返回false吧!
    2. 如果当前要找的字母已经是单词的最后一个字母了,那说明我们已经找完了呀,那直接返回true了。
  2. 没满足终止条件,那说明我们已经走在当前这个格子上了,而且还得往后继续走,那我们得标记一下,防止后面重复走了这个格子。就创建一个flag二维数组好了,大小刚好为网格的大小,可以标记到每一个网格!

    现在我们把flag[x][y]设置为true。

  3. 好了,那我们得继续往后面探索了,先看看四周的格子能走吗?

    • 首先得考虑下我们是不是在地图边界了,如果在地图边界的话,那有些方向就不能走了,不然我就越界了,这很不好。
    • 其次我们还得考虑下哪些方向的格子是走过的,哪些是没走过的。记得我们刚刚用 flag 二维数组来记录了所有走过的格子,所以我只要判断下四周的位置在flag里哪些的值是false,只有这些地方是可以进一步探索的。
  4. 我已经确定好要走哪些格子了,那我得往后走了。递归的时候,我得把下一个位置的坐标传过去,还有标记着已经走过路径的flag数组。也千万别忘了告诉下一层递归它要找的字母,就是我刚找到的那个字母的下一个(index + 1)。

  5. 递归的过程中会重复我们上面的步骤,当递归结束回来的时候,也会带回来我们在第一步设置的返回条件,找到了就是true,没找到就是false。

    那虽然我们同时往几个方向都走过了,但只要其中一个方向返回true,就说明有一条路径是符合条件的,那我们就返回true,要是都没找到,那我们就返回false。

这段解题思路比较冗长且无聊,建议结合下面的核心代码一起理解:

核心代码:

char[][] board; // 网格,由题目提供数据
String word; // 要找的单词,题目提供

int[] sitx = {-1,0,1,0}; // 用来走格子的方向,可以减少重复代码
int[] sity = {0,-1,0,1};

// x和y表示当前坐标
// index表示当前已经走到第几个字母了
// flag表示已经走过的路径,其中走过的值为true
boolean find(int x, int y, int index ,boolean[][] flag) {
    // 如果当前格子的字母不是要找的,直接返回false
    if (word.charAt(index) != board[x][y]) {
        return false;
    }
    // 已经找到最后一个字母了,直接返回true
    if (index == word.length() - 1) {
        return true;
    }
    // 当前这个格子已经走了,给flag赋值
    flag[x][y] = true;
    for (int i = 0 ; i < 4; i++) {
        // 下一步要走的位置nextx、nexty
        int nx = x + sitx[i];
        int ny = y + sity[i];

        // 判断是否超过边界,以及是否已经走过
        boolean isEdge = nx == -1 || nx == board.length || ny == -1 || ny == board[0].length;
        if (isEdge || flag[nx][ny]) continue;

        // 如果没有走过,就往这个方向走
        boolean isFand = find(nx, ny, index + 1, flag);
        // 如果找到了直接返回
        if (isFand) return true;

    }
    // 没有找到格式的路径,返回上一级之前记得清理flag
    flag[x][y] = false;
    return false;
}

好,交一发!当然通过了,但速度不快,应该还能优化,但我看官方题解,却没有看到优化方法。

image-20230115212007372

完整解题代码 Java

class Solution {
    public boolean exist(char[][] board, String word) {
        int n = board.length;
        int m = board[0].length;
        this.word = word;
        this.board = board;
        // 寻找起点,并开启第一步
        for (int i = 0 ; i < n; i++ ) {
            for (int j = 0 ; j < m ; j++) {
                if (board[i][j] == word.charAt(0)) {
                    boolean isFand = find(i, j, 0, new boolean[n][m]);
                    if (isFand) return true;
                }
            }
        }

        return false;
    }

    // 把上面的核心代码放在这即可

}

由于上面已经贴了核心代码了,所以这里我就只贴了其他的部分,如果要提交到LeetCode进行测试的话,记得要把前面的核心代码贴过来噢。

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

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

相关文章

css03笔记

目录 css三大特性 优先级 权重叠加计算 chrome调试工具 盒子模型 1.1 盒子模型的介绍 2.1内容的宽度和高度 3.1边框&#xff08;border&#xff09; 3.2边框-单方向设置 3.3边框-单个属性 综合案例一&#xff08;新浪导航&#xff09; 4.1 内边距&#xff08;paddi…

5.11回溯法--电路板排列问题--排列树

问题描述 将n块电路板以最佳排列插入带有n个插槽的机箱中&#xff0c;要求对于给定的电路板连接块&#xff0c;确定最佳排列&#xff0c;使其具有最小的密度。设x[ ] 表示n块电路板的一个排列&#xff0c;x[ i ]表示在机箱的第 i 个插槽中插入电路板x[ i ]&#xff0c;x确定的电…

尚硅谷ES6李强笔记

1.课程介绍 1.es是什么 2.新特性的优点 3.学习课程必备知识背景 2.相关名词介绍 3. let变量声明以及声明特性 3.1变量声明方式 //普通声明 let a;//一次性声明多个变量 let a,b,c;//声明并且初始化 let a 100;//一次性声明多个并且初始化 let a2,b1,ci love you;3.2不允许重…

打工人必学的法律知识(一)——《中华人民共和国劳动合同法》必知必会

目录 一、劳动合同无效或者部分无效 二、竞业限制 三、劳动合同的履行和变更 四、劳动合同的解除和终止 一、劳动合同无效或者部分无效 第二十六条 下列劳动合同无效或者部分无效&#xff1a;&#xff08;一&#xff09;以欺诈、胁迫的手段或者乘人之危&#xff0c;使对方…

使用FFmpeg命令处理音视频

文章目录前言一、ffprobe相关命令1.使用ffprobe查看音频文件的信息2.使用ffprobe查看视频文件的信息二、ffplay相关命令1.基本的ffplay命令2.音视频同步命令三、ffmpeg相关命令1.ffmpeg通用参数2.ffmpeg视频参数3.ffmpeg音频参数4.ffmpeg示例总结前言 FFmpeg是一套可以用来记录…

【C语言】字符函数,字符串函数,内存函数及其模拟实现

文章目录求字符串长度strlen长度不受限制的字符串函数strcpystrcatstrcmp长度受限制的字符串函数strncpystrncatstrncmp字符串查找函数strstrstrtokstrerror字符函数字符分类函数字符转换函数内存操作函数memcpymemmovememsetmemcmp求字符串长度 strlen 函数功能 求字符串长…

【机器学习之模型融合】Voting投票法简单实践

目录 前言&#x1f49c; 1、使用sklearn实现投票法&#x1f494; 1.1、导入工具库&#xff0c;准备数据&#x1f495; 1.2、定义交叉验证评估函数&#x1f496; 1.3、建立基于交叉验证的benchmark、做模型选择&#x1f31f; 1.4、构建多组分类器、进行融合&#x1f4a5;…

单线程的Node.js能开发高并发服务器程序吗?

文章目录前言Nodejs的事件驱动机制EventLoop vs NSRunLoopNSRunLoopios next runloop异步/事件循坏机制的那些坑批量迁移数据原子性参考文献前言 这篇文章还是从一个在写Node.js程序中遇到的问题说起。本周在做数据库迁移的时候&#xff0c;写了下面一段代码&#xff0c;目的是…

代数与逻辑:作业四 神经网络

代数与逻辑&#xff1a;作业四 神经网络 文章目录代数与逻辑&#xff1a;作业四 神经网络一、作业要求二、简述神经网络模型三、编程实现感知机模型与二隐层神经网络1、感知机模型2、二隐层神经网络四、选择公开数据集&#xff0c;测试感知机模型与二隐层神经网络性能一、作业要…

如何高效学习?一年学完麻省理工4年计算机课程

斯科特.杨用用10天拿下线性代数&#xff0c;用1年时间学完麻省理工大学4年的计算机课程&#xff0c;他是如何做到的&#xff1f;他在这本书《如何高效学习》中做了具体阐述。 斯科特.杨很早就发现&#xff0c;在美国有一半的学生在死记硬背&#xff0c;这些学生并不知道使用整体…

动手学区块链学习笔记(二):区块链以及工作量证明算法

引言 紧接上文&#xff0c;在介绍完区块链中的加密解密以及公钥私钥等算法后&#xff0c;本篇开始正式进入区块链概念与一个简单区块链系统的实现过程介绍。 区块链技术介绍 什么是区块链&#xff1f; 区块链&#xff0c;就是一个又一个区块组成的链条。每一个区块中保存了一…

制造企业数据/经营分析框架

背景 随着大数据技术发展以及数字化转型概念的普及&#xff0c;传统企业特别是制造业&#xff0c;也开始投入人力、资金&#xff0c;建立自己的数据分析团队&#xff0c;期望通过数据分析赋能企业的发展/转型。尽管&#xff0c;国内华为、美的、海尔、三一、徐工等制造业龙头企…

挡不住,逃不过,还是阳了

自从放开后&#xff0c;身边的&#x1f40f;陆陆续续多了起来。现在都不敢在食堂吃饭了&#xff0c;每次都是打包到工位吃&#xff0c;上班时也是都戴着口罩。每天回家后都是一顿扫射&#xff0c;用医用酒精做全身消毒。但是&#xff0c;还是没挡住&#xff0c;该来的还是来了。…

Leetcode:450. 删除二叉搜索树中的节点(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 递归&#xff1a; 原理思路&#xff1a; 含有内存释放版&#xff1a; 问题描述&#xff1a; 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜…

Day860.高性能数据库连接池HiKariCP -Java 并发编程实战

高性能数据库连接池HiKariCP Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于高性能数据库连接池HiKariCP的内容。 实际工作中&#xff0c;总会难免和数据库打交道&#xff1b; 只要和数据库打交道&#xff0c;就免不了使用数据库连接池。 业界知名的数据库连接池…

2023/1/15 JS-作用域与作用域链

1 作用域 理解 - 就是一块"地盘", 一个代码段所在的区域&#xff0c;它是静态的(相对于上下文对象), 在编写代码时就确定了 分类&#xff1a; 全局作用域函数作用域 没有块作用域(ES6有了) -->(java语言也有) if (true) {var a 3}console.log(a); // 3作用&am…

用互联网思维做产品,做超出用户预期的产品

做出超出用户预期的产品&#xff0c;做出让用户惊喜和兴奋的产品。超越用户期望极致体验极致服务极致产品(极致产品功能情感温度)关心、关注、尊重用户理解用户理解人性用户参与。只有深刻了解&#xff0c;深刻理解用户&#xff0c;深刻理解人性&#xff0c;才能做出好的产品。…

Maven安装教程讲解

目录一、下载安装JDK二、下载 Maven三、配置 Maven 环境变量四、配置 Maven 仓库地址五、配置 Maven 镜像六、配置 Maven JDK七、IDE配置 Maven八、IDE新建 Maven 项目九、IDE执行 Maven 命令一、下载安装JDK 教程&#xff1a;https://blog.csdn.net/weixin_43888891/article/…

【阶段四】Python深度学习09篇:深度学习项目实战:循环神经网络处理时序数据项目实战:CNN和RNN组合模型

本篇的思维导图: 项目背景 时间序列数据集中的所有数据都伴随着一个时戳,比如股票、天气数据。这个数据集,是科学家们多年间用开普勒天文望远镜观察并记录下来的银河系中的一些恒星的亮度。广袤的宇宙,浩瀚的星空在过去很长一段时间里,人类是没有办法证明系外行星…

关于一次python服务性能的问题分析定位

今天项目遇到一个比较棘手的问题&#xff0c;我们做的接口平台&#xff0c;提供了一个给用户自己编辑关键字的逻辑&#xff0c;发现对应服务的cpu基本都满了&#xff0c;并且通过扩容的方式也没有好转&#xff0c;也同样被打满。 找了测试的同学了解了下&#xff0c;发现他们使…