LeetCode题练习与总结:单词搜索--79

一、题目描述

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

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

示例 1:

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

示例 2:

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

示例 3:

输入: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 仅由大小写英文字母组成

二、解题思路

  1. 遍历整个二维网格,对于每一个格子,都以它为起点进行深度优先搜索(DFS)。
  2. 在DFS中,检查当前字符是否匹配单词的当前字符。
  3. 如果匹配,标记当前位置已访问,并递归地访问它的四个邻居(上、下、左、右)。
  4. 如果在某个时刻,我们已经访问了单词的所有字符,并且它们都匹配,那么返回true。
  5. 如果在任何时刻字符不匹配或者已经没有更多的邻居可以访问,那么回溯,撤销最后一步的标记,并返回false。
  6. 如果所有起点都尝试过,仍未找到匹配的单词,那么返回false。

三、具体代码

class Solution {
    private int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 四个方向:右、下、左、上

    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        boolean[][] visited = new boolean[m][n]; // 记录是否访问过

        // 遍历整个网格
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (dfs(board, word, 0, i, j, visited)) {
                    return true; // 找到匹配,返回true
                }
            }
        }

        return false; // 没有找到匹配,返回false
    }

    private boolean dfs(char[][] board, String word, int index, int x, int y, boolean[][] visited) {
        // 如果已经访问过word的所有字符,返回true
        if (index == word.length()) {
            return true;
        }

        // 检查当前坐标是否越界或者字符不匹配或者已经访问过
        if (x < 0 || x >= board.length || y < 0 || y >= board[0].length || visited[x][y] || board[x][y] != word.charAt(index)) {
            return false;
        }

        // 标记当前位置已访问
        visited[x][y] = true;

        // 尝试访问四个方向的邻居
        for (int[] direction : directions) {
            int newX = x + direction[0];
            int newY = y + direction[1];
            if (dfs(board, word, index + 1, newX, newY, visited)) {
                return true;
            }
        }

        // 回溯,撤销访问标记
        visited[x][y] = false;

        return false;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 对于每个单元格,我们可能需要进行深度优先搜索(DFS),最坏情况下,DFS会访问每个单元格一次。
  • 单词的长度为 L,网格的大小为 m x n
  • 在 DFS 中,我们最多会访问每个单元格四次(上、下、左、右)。
  • 因此,时间复杂度为 O(m * n * 4^L)。这里的 4^L 是因为每次我们都有四个方向可以选择,并且我们可能需要探索单词的每个字符。
2. 空间复杂度
  • 空间复杂度主要取决于递归调用栈的深度以及用于标记访问过的 visited 数组。
  • 递归调用栈的最大深度为 L,即单词的长度。
  • visited 数组的大小为 m x n
  • 因此,空间复杂度为 O(m * n + L)

(在这里,L 是单词的长度,m 和 n 分别是网格的行数和列数。)

五、总结知识点

  1. 回溯算法:这是一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会通过在上一步进行一些变化丢弃该解,即回溯并且再次尝试。

  2. 深度优先搜索(DFS):这是一种用于遍历或搜索树或图的算法。沿着一个分支走到底,直到该路径上的最后一个节点被访问,然后回溯至上一个分叉点,继续遍历其他分支。

  3. 递归:这是一种编程技巧,函数自己调用自己。在DFS中经常使用递归,因为它非常适合用于探索分支。

  4. 二维数组:代码中的 board 是一个二维字符数组,用于表示棋盘或网格。二维数组是数组的数组,可以用来表示矩阵或其他格状结构。

  5. 布尔数组visited 是一个布尔类型的二维数组,用于跟踪在DFS过程中哪些位置已经被访问过,以避免重复访问同一个单元格。

  6. 边界检查:在访问网格的每个位置时,代码都会检查当前位置是否越界,即是否超出了数组的界限。

  7. 字符比较:代码中使用 board[x][y] != word.charAt(index) 来检查当前网格中的字符是否与单词中的相应字符匹配。

  8. 循环和条件语句:代码中使用了 for 循环来遍历网格的每个单元格,以及 if 语句来检查各种条件,如字符匹配、越界等。

  9. 数组初始化:在 exist 方法中,directions 数组和 visited 数组被初始化,以备后续使用。

  10. 方法重载exist 和 dfs 是两个不同的方法,它们具有相同的名字 exist,但是参数列表不同,这是方法重载的例子。

  11. 引用传递:在 dfs 方法中,visited 数组是通过引用传递的,这意味着在 dfs 中的任何修改都会影响到原始的 visited 数组。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Airmail 5 for Mac:高效电子邮件管理软件

Airmail 5 for Mac作为一款功能强大的电子邮件客户端软件&#xff0c;为Mac用户带来了全新的邮件管理体验。其高效、直观的操作界面&#xff0c;使得用户可以轻松管理各类邮件&#xff0c;提升工作效率。 Airmail 5 for Mac v5.7.4中文激活版 首先&#xff0c;Airmail 5支持多个…

二叉搜索树(Binary_Search_Tree)

文章目录 二叉搜索树概念二叉搜索树的操作查找插入删除 二叉搜索树的应用二叉搜索树的实现K模型KV模型 二叉搜索树的性能分析 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&a…

计算机网络面试高频:输入域名会发生那些操作,开放性回答

更多大厂面试内容可见 -> http://11come.cn 计算机网络面试高频&#xff1a;输入域名会发生那些操作&#xff0c;开放性回答 输入域名之后&#xff0c;会发生哪些操作&#xff1f; 当在浏览器中输入www.baidu.com并按下回车键时&#xff0c;会触发一系列复杂的网络过程&am…

MMSeg搭建自己的网络

配置结构 首先&#xff0c;我们知道MMSeg矿机的配置文件很多&#xff0c;主要结构如下图所示。 在configs/_base_下是模型配置、数据集配置、以及一些其他的常规配置和运行配置&#xff0c;四类。 configs/all_config目录下存放&#xff0c;即是将四种配置聚合在一起的一个总…

互联网的下个风口可能是供应链和B2B行业的创新

6年前我写过一篇文章叫做《所有B2B从业者都会遇到的9个问题》&#xff0c;这篇文章也同步发布在了我的知乎以及CSDN博客上面。几个平台陆续有读者通过私信和留言向我咨询一些问题&#xff0c;刚好这2年我对B2B又有了一些新的思考&#xff0c;于是就针对前些年的那篇文章做一些补…

ubuntu22.04安装TensorRT(过程记录)

重要说明&#xff1a;此贴经过多次修改。第一次安装的的为trt8.6.1版本。第二次安装的10.0.0.6版本。有些地方可能没改过来&#xff0c;比如链接向导&#xff0c;我懒得改了&#xff0c;但是流程是对的。 cuda和cudnn版本对应关系 tensorRT历史发行版本 CUDA历史发行版本 cudn…

【Linux】make 和 makefile

进度条 #pragma once#include <stdio.h>#define NUM 102 #define BODY #define TOP 100 #define RIGHT >extern void processbar(int rate);#include "processBar.h" #include <string.h> #include <unistd.h>const char lable[] "|/-\…

【限时免费】Adobe全家桶免费领取 一键安装,永久使用 全家桶大礼包破解直装版 2020-2024 设计师御用超全软件 值得收藏

一次购买&#xff0c;终生使用&#xff01;正版永久激活&#xff0c;免费一键安装&#xff0c;赠送学习视频教程&#xff0c;支持远程安装&#xff0c;安装失败&#xff0c;立即退款。无需付费&#xff0c;直接免费送&#xff01; Adobe全家桶&#xff08;Adobe Creative Clou…

【Canvas与艺术】绘制美国星条旗

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>使用HTML5/Canvas绘制美国星条旗</title><style type"…

舌头分割YOLOV8-SEG

舌头分割&#xff0c;基于YOLOV8-SEG&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;从而摆脱YOLO依赖&#xff0c;支持C,PYTHON,ANDROID开发 舌头分割YOLOV8-SEG

Gromacs——教程学习(1)

分子动力学模拟&#xff08;Molecular Dynamics&#xff09;全流程 所有的xvg格式文件&#xff0c;都可以使用大神编写的python DuIvyTools脚本可视化&#xff0c;很方便&#xff0c;只要你的电脑配置了python或者anaconda或者miniconda pip install DuIvyToolsdit xvg_show -…

Blender面操作

1.细分Subdivide -选择一个面 -右键&#xff0c;细分 -微调&#xff0c;设置切割次数 2.删除 -选择一个或多个面&#xff0c;按X键 -选择要删除的是面&#xff0c;线还是点 3.挤出面Extrude -选择一个面 -Extrude工具 -拖拽手柄&#xff0c;向外挤出 -微调&#xff…

构建中小型企业网络-单臂路由

1.给IP地址配置好对应的IP和网关 2.配置交换机 3.路由配置 在交换机ge0/0/1中配置端口为trunk是可以允许多个vlan通过的&#xff0c;但路由器是不能够配置vlan&#xff0c;而交换机和路由器间连接的只有一根线&#xff0c;一个端口又只能配置一个ip地址&#xff0c;只有一个ip地…

内网穿透及公网解析说明

内网穿透释义&#xff1a; 自己在本地搭建服务器时&#xff0c;本地网络有多种环境&#xff0c;如没有公网IP、没有路由映射权限、网络被NAT转发等情况。在需要外网访问内网服务器资源时&#xff0c;就需要用到内网穿透。内网穿透&#xff0c;即内网映射&#xff0c;内网IP地址…

vue3中使用animate.css

在vue3中使用animate.css 20240428_093614 引入&#xff1a;npm install animate.css --save main.js注册&#xff1a;import ‘animate.css/animate.min.css’ 注意&#xff1a;import ‘animate.css’ 不适合在vue3项目 使用&#xff1a;class“animate__animated 动画名称”…

艾宾浩斯记忆曲线记忆法,艾宾浩斯遗忘曲线计划表

一、资料前言 本套遗忘曲线复习计划表&#xff0c;大小59.22M&#xff0c;1个压缩文件。 二、资料目录 00 艾宾浩斯视频介绍 01 艾宾浩斯表格&#xff08;智能电子版&#xff09; 02 艾宾浩斯表格&#xff08;可编辑可打印&#xff09; 03 日周月计划表 04 一些好用的表…

通过中缀表达式转后缀表达式计算复杂表达式

栈操作与表达式解析&#xff1a;从基础到实践 在计算机科学中&#xff0c;栈是一种常用的数据结构&#xff0c;它遵循后进先出&#xff08;LIFO&#xff09;的原则。本文将通过一系列函数的实现&#xff0c;探讨栈在括号匹配、中缀表达式转换为后缀表达式以及后缀表达式求值中…

终端安全管理软件哪个好?

终端安全管理软件是保障企业信息安全的重要工具。 它们能够有效地防范恶意软件、黑客攻击和其他安全威胁&#xff0c;并提供多方面的终端设备安全保护措施。 终端安全软件的功能和保护机制各不相同&#xff0c;这就需要企业根据自身的需求和情况来进行评估和选择。 下面总结了…

自动化测试

自动化测试 1、quit() 和 close()的区别2、窗口切换3、截图操作 1、quit() 和 close()的区别 1、quit() 是关闭整个浏览器&#xff1b;而close() 是关闭当前的页面&#xff1b; 2、quit() 操作会清空缓存&#xff1b;close() 不会清空缓存&#xff1b; 2、窗口切换 private …

Python 语音识别系列-实战学习-语音识别特征提取

Python 语音识别系列-实战学习-语音识别特征提取 前言1.预加重、分帧和加窗2.提取特征3.可视化特征4.总结 前言 语音识别特征提取是语音处理中的一个重要环节&#xff0c;其主要任务是将连续的时域语音信号转换为连续的特征向量&#xff0c;以便于后续的语音识别和语音处理任务…
最新文章