java数据结构与算法刷题-----LeetCode79. 单词搜索

news2024/10/12 20:22:13
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

文章目录

    • 回溯+深度优先遍历

在这里插入图片描述

回溯+深度优先遍历

解题思路:时间复杂度O( m ∗ n + s ∗ n u m m*n + s*num mn+snum),m*n是将整个board数组遍历了一遍,s是字符串word的长度,num是word这个字符串的第一个字符在board出现了几次。空间复杂度O( m ∗ n ∗ 2 m*n*2 mn2)
  1. 先创建一个hash表,key保存board中出现的字符,value保存对应字符的所有坐标,所需时间复杂度O( m ∗ n m*n mn),空间复杂度O( m ∗ n m*n mn)
  2. 然后查看hash表,是否缺少word中的字符,因为缺少哪怕一个字符,都无法完成word的搜索,直接返回false即可。时间复杂度可以忽略不计
  3. 从hash表获取word第一个字符的所有下标p,并遍历,所需时间复杂度为O(num),num为word中第一个字符在board的所有下标个数

每次遍历都需要visited数组标识我们本次路径上访问的位置,因为同一个位置不能访问多次,空间复杂度O( m ∗ n m*n mn)

  1. 以每个p为起点进行深度优先遍历(从上下左右四个方向依次比对),如果当前路径没有访问这个结点,并且成功和word中当前字符对应,就继续遍历。当整个word字符串都成功比对,就返回true。
  2. 如果当前字符没有成功比对,就将当前位置的visited设置回false表示这个位置下次可以继续访问。然后回溯到上一步继续深度优先遍历
代码

在这里插入图片描述

class Solution {
    char[][] board;
    String word;
    int [][] directions = new int[][]{{-1,0},{0,-1},{1,0},{0,1}};//移动方向标量:上左下右
    public boolean exist(char[][] board, String word) {
        //将通用内容保存,不进行传参,否则降低代码可读性
        this.board = board;
        this.word = word;
        int row = board.length;
        int col = board[0].length;
        //将board中出现的每个字母的下标保存起来,key为字母,value为这个字母的下标
        Map<Character, List<int[]>> dict = new HashMap<>();
        for (int r = 0; r < row; r++) {
            for (int c = 0; c < col; c++) {
                List<int[]> val = dict.getOrDefault(board[r][c], new ArrayList<>());//如果字母第一次出现,就初始化
                val.add(new int[]{r, c});//将当前下标添加
                dict.put(board[r][c], val);
            }
        }
        //如果有要查找的单词中有字母不在字典,就返回false
        for (char ch : word.toCharArray()) {
            if (!dict.containsKey(ch)) return false;
        }
        //否则进行dfs查找,遍历word中第一个字母的所有下标
        for (int[] p : dict.get(word.charAt(0))) {//从第一个字母开始查找,其它的就不用找了,因为必须第一个字母开头
            boolean ret = dfs(p[0], p[1], new boolean[row][col], 0);//深度优先遍历查找
            if (ret) return true;//找到了就返回true
        }
        return false;//否则返回false
    }
    
    /**
     * 深度优先遍历
     * @param r 横坐标
     * @param c 纵坐标
     * @param path 当前查找访问路径,因为不可以重复
     * @param index //当前正在比对word中第几个字母
     * @return 是否完成word的搜索,是就返回true
     */
    private boolean dfs(int r, int c, boolean[][] path, int index) {
        int row = board.length;
        int col = board[0].length;
        if (index >= word.length()) return true;//所以字母比对完成就返回true
        //如果下标越界或者当前结点已经访问过,就返回false
        if (r < 0 || r >= row || c < 0 || c >= col || path[r][c]) return false;
        //开始回溯遍历
        char ch = word.charAt(index);//获取当前要比对的字母
        if (board[r][c] != ch) return false;//如果当前位置和字母对应不上,返回false
        //如果比对成功,设置当前位置已经访问过
        path[r][c] = true;
        //进行上下左右遍历,下面这个写法虽然稍微多遍历了几次(就很少的几次而已),但是代码可读性更高。
        //如果真的追求3ms的差距,可以选择用更下面注释的写法
        boolean ret = false;//默认比对失败
        for(int[] direction: directions){//获取上下左右移动标量
            int nextR = r+direction[0];//移动后横坐标
            int nextC = c+direction[1];//移动后纵坐标
            ret = dfs(nextR,nextC,path,index+1);//对其进行遍历
            if(ret) return true;//如果比对成功,返回true;
        }
        path[r][c] = false;//否则表示当前路径比对失败,将其设置为可访问状态
        return false;//比对失败,返回false。继续回溯
    //以下写法和上面写法的效果一样。虽然耗时更小(少一点点,3ms),但是代码非常不好看
    //    boolean ret = dfs(r + 1, c, path, index + 1);
    //    if (ret) return true;
       
    //    ret = dfs(r - 1, c, path, index + 1);
    //    if (ret) return true;
       
    //    ret = dfs(r, c + 1, path, index + 1);
    //    if (ret) return true;
       
    //    ret = dfs(r, c - 1, path, index + 1);
    //    if (ret) return true;
       
        // path[r][c] = false;
        // return false;
    }
}

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

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

相关文章

Vue 大文件切片上传实现指南包会,含【并发上传切片,断点续传,服务器合并切片,计算文件MD5,上传进度显示,秒传】等功能

Vue 大文件切片上传实现指南 背景 在Web开发中&#xff0c;文件上传是一个常见的功能需求&#xff0c;尤其是当涉及到大文件上传时&#xff0c;为了提高上传的稳定性和效率&#xff0c;文件切片上传技术便显得尤为重要。通过将大文件切分成多个小块&#xff08;切片&#xff0…

Rust线程间通信通讯channel的理解和使用

Channel允许在Rust中创建一个消息传递渠道&#xff0c;它返回一个元组结构体&#xff0c;其中包含发送和接收端。发送端用于向通道发送数据&#xff0c;而接收端则用于从通道接收数据。不能使用可变变量的方式&#xff0c;线程外面修改了可变变量的值&#xff0c;线程里面是拿不…

UE5启用SteamOS流程

一、安装OnlineSubsystemSteam插件 1、在UE里安装OnlineSubsystemSteam 2、设置默认开始地图 3、设置DefaultEngine.ini文件&#xff1a; 打开项目根目录/Config/DefaultEngine.ini文件 打开官网的配置说明 复制并粘贴到该文件中 4、设置运行模式 5、测试 确保Steam平台已…

云原生:应用敏捷,华为视角下的应用现代化

Gartner 也提出&#xff0c;到 2023 年&#xff0c;新应用新服务的数量将达到 5 亿&#xff0c;也即是说&#xff1a;“每个企业都正在成为软件企业”。据IDC 预测&#xff0c;到 2025 年三分之二的企业将成为多产的“软件企业”&#xff0c;每天都会发布软件版本。越来越多的企…

【HTML】简单制作一个动态3D正方体

目录 前言 开始 HTML部分 JS部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;JS的文件名改…

基于Python深度学习的中文情感分析系统(V2.0)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

v3-admin-vite 改造自动路由,view页面自解释Meta

需求 v3-admin-vite是一款不错的后端管理模板&#xff0c;主要是pany一直都在维护&#xff0c;最近将后台管理也进行了升级&#xff0c;顺便完成一直没时间解决的小痛痒&#xff1a; 在不使用后端动态管理的情况下。我不希望单独维护一份路由定义&#xff0c;我希望页面是自解…

STM32的定时器中断Cubemx

STM32的定时器中断Cubemx 0.定时器简介1.配置时钟2.配置定时器3.创建工程4.补充源码 0.定时器简介 基本定时器功能&#xff1a; 16位向上、向下、向上/下自动装载计数器16位可编程(可以实时修改)预分频器&#xff0c;计数器时钟频率的分频系数为1&#xff5e;65535之间的任意…

BGP-(as-path-filter)

BGP-as-path-filter&#xff0c;缺省 as-path-filter&#xff0c;正则表达式&#xff0c;as-path过滤器&#xff0c;对于BGP的as-path属性实际上可以看成是一个包含空格的字符串。 特点&#xff1a;1、通过对BGP路由的as-path属性进行匹配达到对BGP路由的过滤。 2、在route-…

Vue组件封装重要知识点

一、什么是组件&#xff1f; Vue.js的一个核心思想是组件化。所谓组件化&#xff0c;就是把页面拆分成多个组件&#xff0c;每个组件依赖的CSS、JavaScript、模板、图片等资源放在一起开发和维护。组件是资源独立的&#xff0c;组件在系统内部可复用&#xff0c;组件和组件之间…

时序预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络时间序列预测

时序预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-BiLST…

目标检测——图像中提取文字

一、重要性及意义 图像提取文本&#xff0c;即光学字符识别&#xff08;OCR&#xff09;技术&#xff0c;在现代社会中的重要性和意义日益凸显。以下是关于图像提取文本的重要性和意义的几个关键方面&#xff1a; 信息获取的效率提升 快速处理大量文档&#xff1a;OCR技术可…

基于AI智能识别技术的智慧展览馆视频监管方案设计

一、建设背景 随着科技的不断进步和社会安全需求的日益增长&#xff0c;展览馆作为展示文化、艺术和科技成果的重要场所&#xff0c;其安全监控系统的智能化升级已成为当务之急。为此&#xff0c;旭帆科技&#xff08;TSINGSEE青犀&#xff09;基于视频智能分析技术推出了展览…

OpenHarmony实战:标准系统移植指南

本文描述了移植一块开发板的通用步骤&#xff0c;和具体芯片相关的详细移植过程无法在此一一列举。后续社区还会陆续发布开发板移植的实例供开发者参考。 定义开发板 本文以移植名为MyProduct的开发板为例讲解移植过程&#xff0c;假定MyProduct是MyProductVendor公司的开发板…

区间概率预测python|QR-CNN-BiLSTM+KDE分位数-卷积-双向长短期记忆神经网络-时间序列区间概率预测+核密度估计

区间预测python|QR-CNN-BiLSTMKDE分位数-卷积-双向长短期记忆神经网络-核密度估计-回归时间序列区间预测 模型输出展示&#xff1a; (图中是只设置了20次迭代的预测结果&#xff0c;宽度较宽&#xff0c;可自行修改迭代参数&#xff0c;获取更窄的预测区间&#xff09; 注&am…

基于java实现的弹幕视频网站

开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclip…

mongoDB 优化(2)索引

执行计划 语法&#xff1a; db.collection_xxx_t.find({"param":"xxxxxxx"}).explain(executionStats) 感觉这篇文章写得很好&#xff0c;可以参考 MongoDB——索引&#xff08;单索引&#xff0c;复合索引&#xff0c;索引创建、使用&#xff09;_mongo …

【办公类-48-01】20240404每月电子屏台账汇总成docx(问卷星xlsx导入docx,每页20条)

作品展示——docx台账汇总&#xff0c;每页20条 背景需求&#xff1a; 近期上级要求“一屏一码”&#xff0c;幼儿园每个电子屏使用后都要进行开机、关机的记录。安全主任分配工作后&#xff0c;每个园区的每个电子屏都有专人负责登记。 为了便于每月末的台账提交&#xff08;…

使用Java拓展本地开源大模型的网络搜索问答能力

背景 开源大模型通常不具备最新语料的问答能力。因此需要外部插件的拓展&#xff0c;目前主流的langChain框架已经集成了网络搜索的能力。但是作为一个倔强的Java程序员&#xff0c;还是想要用Java去实现。 注册SerpAPI Serpapi 提供了多种搜索引擎的搜索API接口。 访问 Ser…

华为服务器RAID配置教程 服务器硬盘故障处理帮助 浪潮RAID配置教程 磁盘阵列配置通用教程

前言&#xff08;本文档持续更新&#xff09; 本文主要记录服务器配置RAID&#xff08;磁盘阵列&#xff09;过程中存在的细节问题及官方文档无法解决的问题的解决方案 配置环境 华为 RH2288 v3服务器配置RAID组 如何快速配置 1.找到服务器品牌的阵列卡型号&#xff0c;找不到…