212. Word Search II:多个单词查找

写在前面:这两周持续看花花酱整理的题目列表和视频讲解,也得益于自己持续多年刷题,今天刷这道题目的想法是:会trie树居然就能攻克hard题目!我也离独立攻破hard题目不远了嘛。前段时间看王争在极客时间的系列课程,trie树是不在话下的。好,开始写题。

目录

  • 题目描述
  • 暴力回溯
  • Trie树

题目描述

输入:二维字符数组,做棋盘baord;字符串列表words。
返回:可以在棋盘中找到的所有单词word。
规则:每个单词需要按顺序在棋盘中匹配,棋盘匹配的时候只能移动相邻位置。相邻位置是指上下左右。
例子:输入
board = [
[‘o’,‘a’,‘a’,‘n’],
[‘e’,‘t’,‘a’,‘e’],
[‘i’,‘h’,‘k’,‘r’],
[‘i’,‘f’,‘l’,‘v’]
]
words = [“oath”,“pea”,“eat”,“rain”]

输出: [“eat”,“oath”]

暴力回溯

按照回溯法,每次解决一个单词word。可以参考题目79。
参考例子中,board的行列:m=4,n=4。查找单词word=oath。dfs搜索的时候每找到单词中的一个字符作为一层。在每一层向下一层移动过程中有上、下、左、右4种选择。
枚举每一个位置(i,j)作为起始查找位置。因为不确定哪个位置的ch与word的第一个字符相同。

dfs(i,j,index),i:第i行;j:第j列;index:单词中的第index个字符。
如果 board[i][j]=word[index],则设置board[i][j]=’#’,防止重复查找,继续向4个方向遍历。
当index=word.length的时候,表示word是存在的,加入结果集。
当数组下标i,j越界,或者重复查找的时候返回。
如果board[i][j]!=word[index],则返回,不继续搜索。

最终每个单词查找一次,返回结果。
时间复杂度:$O(m∗n∗4l)O(m*n*4^l)O(mn4l),l=单词长度

class Solution {private char[][] board;private String word;private int m;private int n;public List<String> findWords(char[][] board, String[] words) {this.board = board;m = board.length;if(m == 0) return new ArrayList<String>();n = board[0].length;List<String> result = new ArrayList<String>();for(String word : words){if(findWord(word)){result.add(word);}}return result;}private boolean findWord(String word) {this.word = word;for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(dfs(i,j,0)){return true;}}}return false;}private boolean dfs(int i,int j,int index){if(index == word.length()) return true;if(i<0 || i>=m || j<0 || j>=n || board[i][j]=='#'){return false;}boolean r = false;if(board[i][j] == word.charAt(index)){char ch = board[i][j];board[i][j] = '#';r = dfs(i-1,j,index+1)|| dfs(i+1,j,index+1)|| dfs(i,j-1,index+1)|| dfs(i,j+1,index+1);board[i][j] = ch;}return r;}
}

Trie树

这里需要查找多个单词。例如word=[“baa”,“bab”,“aaab”,“aaa”,“aaaa”]。单词baa和bab有公共前缀ba,暴力回溯每次都从0开始查找,浪费时间。如果能查找到baa之后回溯一步,继续查找到bab就好了。单词aaa和aaaa,也是同样的情况。这里就需要用到Trie树。Trie树在有公共前缀子串的情况下,会极大的降低时间复杂度。Trie树学习可以参考我的博客。
在这里插入图片描述

上图展示了构建完成的Trie树结构。这里在每个单词结束位置添加了word表示当前字符串的值。便于记录结果。

和暴力回溯类似,遍历每一个起始位置(i,j),从根节点开始查找。
dfs(i,j,node):每次查找到一个节点,word不为空,说明找到了一个字符串,加入结果集并且word设置为null。
数组下标i,j越界,或者重复访问,则返回。
如果node.children[board[i][j]-‘a’]不为空,则继续朝4个方向搜索。否则返回。

时间复杂度:构建trie树的时间复杂度是所有单词长度和:$O(sum(l))。

搜索过程,因为有合并搜索,所以最深的深度是max(l)。在每一层会查找4个方向,所以是O(4max(l))O(4^{max(l)})O(4max(l))

所以最终时间负责度是:O(sum(l)+4max(l))O(sum(l)+4^{max(l)})O(sum(l)+4max(l))

class Solution {private char[][] board;private String word;private int m;private int n;private TrieNode root;private List<String> result;public List<String> findWords(char[][] board, String[] words) {this.board = board;m = board.length;if(m == 0) return new ArrayList<String>();n = board[0].length;result = new ArrayList<String>();buildTree(words);for(int i=0;i<m;i++){for(int j=0;j<n;j++){dfs(i,j,root);}}return result;}private void dfs(int i,int j,TrieNode node){if(node.word!=null){result.add(node.word);node.word = null;}if(i<0 || i>=m || j<0 || j>=n || board[i][j]=='#'){return;}        char ch = board[i][j];if(node.children[ch-'a']==null) return;TrieNode n = node.children[ch-'a'];board[i][j] = '#';dfs(i-1,j,n);dfs(i+1,j,n);dfs(i,j-1,n);dfs(i,j+1,n);board[i][j] = ch;}private void buildTree(String[] words){root = new TrieNode('/');for(String word : words){addWord(word);}}public void addWord(String word){TrieNode p = root;for(int i=0;i<word.length();i++){int idx = word.charAt(i)-'a';if(p.children[idx]==null){p.children[idx] = new TrieNode(word.charAt(i));}p = p.children[idx];}p.end = true;p.word = word;}class TrieNode{private char data;private boolean end;private TrieNode[] children = new TrieNode[26];private String word;public TrieNode(char data){this.data = data;}public boolean isEnd(){return end;}}
}

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

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

相关文章

CNN(卷积神经网络)、RNN(循环神经网络)、DNN(深度神经网络)的内部网络结构区别...

神经网络技术起源于上世纪五、六十年代&#xff0c;当时叫感知机&#xff08;perceptron&#xff09;&#xff0c;拥有输入层、输出层和一个隐含层。输入的特征向量通过隐含层变换达到输出层&#xff0c;在输出层得到分类结果。早期感知机的推动者是Rosenblatt。&#xff08;扯…

在mybatis中调oracle dblink存储过程

写在前面&#xff1a;在mybatis中操作oracle的数据&#xff0c;不复杂&#xff0c;也不困难。只是第一次用&#xff0c;入了很多坑&#xff0c;记录一下。在此之前需要一些简单的配置&#xff0c;此前一篇博客已经做了简单叙述&#xff1a; https://www.cnblogs.com/studentc/p…

spring学习(49):javaconfig里面定义bean的作用域

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

675. Cut Off Trees for Golf Event

这道题目最大的难点是理解题意。 文章目录题目理解题目理解 输入&#xff1a;一个非负的二维数组 输出&#xff1a;一个最短距离 规则&#xff1a;数组中的元素如果是0&#xff0c;表示障碍&#xff0c;不能通过。如果是1&#xff0c;表示可以行走的地面。如果大于1表示树的高…

spring学习(50):延迟加载

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

ansible的错误

错误 [rootbogon ansible]# ansible test -m ping 192.168.16.155 | FAILED! > { "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this hosts finger…

spring学习(51):对象的初始化和销毁

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

282. Expression Add Operators

目录题目理解分析第一步&#xff1a;dfs获得所有表达式第二步&#xff1a;计算结果先计算加减法计算乘法时间复杂度进一步优化题目理解 输入&#xff1a;一个字符串num&#xff0c;一个int target。输入num只包含数字。 规则&#xff1a;可以给num中包含的数字之间任务添加二目…

ubuntu下的对拍

开始用ubuntu祭blog 转载于:https://www.cnblogs.com/123789456ye/p/11094192.html

spring学习(52):工厂方法创建bean对象

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

花花酱leetcode 题目——搜索专题

在刷完极客时间的算法题目之后&#xff0c;偶然看到了花花酱关于leetcode进入千题时代的一些刷题看法。决定跟着他的思路继续刷题。 要刷多少题 1 每个类型 10-20 如何刷题 1 同类型题目一起刷 2 看代码很重要&#xff0c;看至少3-5种不同实现 3 第一遍&#xff1a;5分钟想…

P2058 海港

P2058 海港 题解 这道题就是给出你n艘船&#xff0c;让你看看以当前船停靠时间为截止时间&#xff0c;24h以内乘客来自多少不同的国家 一开始会想到来一艘船就记录下本船的到达时间&#xff0c;到达人数&#xff0c;以及乘客的国籍 但是你会发现这很占空间 而且船只进来的顺序都…

spring mvc学习(1):spring jar包

spring.jar是包含有完整发布的单个jar 包&#xff0c;spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容&#xff0c;因为只有在开发环境下才会用到 spring-mock.jar来进行辅助测试&#xff0c;正式应用系统中是用不得这些类的。 除了spring.jar文件&a…

花花酱leetcode 题目-二分搜索

原链接 IDNamedifficultysimilar Problemscomments35Search Insert Position234 94 781upper_bound33Search in Rotated Sorted Array381 153 154 162rotated/peak69Sqrt(x)

com.alibaba.fastjson.JSONObject cannot be cast to XXX异常解决

项目开发中遇到过几次这个问题&#xff0c;所以记录一下&#xff0c;代码如下&#xff1a; 1 PostMapping("/save-files") 2 public void addFiles(RequestBody List<AddFileRecordRequestDto> fileRecords) 3 { 4 LoginInfo loginInfosession…

spring mvc学习(2):spring jar包下载

jstl的jar包的下载 我们在使用spring框架的时候导入jstl标签库需要使用到jstl的jar包&#xff0c;假如没有加入到eclipse的lib目录下&#xff0c;使用alt /的时候不会有提示&#xff0c;所以我们需要把这个jar包加进来 首先登陆网址&#xff1a;http://tomcat.apache.org/ta…

EF框架学习(5)---EF中的在线和离线场景

EF中的持久性场景 使用EF实现实体持久化&#xff08;保存&#xff09;到数据库有两种情况&#xff1a;在线场景和离线场景。 1.在线场景 在线场景中&#xff0c;context是同一个上下文实例&#xff08;从DbContext派生&#xff09;&#xff0c;检索和保存实体都通过同一个conte…

spring mvc学习(3):建立第一个动态web项目

intellij idea创建第一个动态web项目 我以2018版的intellij idea为例 一.创建JavaWeb 1.第一步 点击左上角的File-->New-->Project 2.第二步 1.找到Java Enterprise之后&#xff0c;在Application Sever中找到自己的Tomcat&#xff0c;同时勾选中Web Application 2.…

Git:(1)简介

Git是一个开源的分布式版本控制系统&#xff0c;分布式相比集中式的最大区别是Git没有“中央服务器”&#xff0c;每位开发者都可以通过克隆&#xff08;git clone&#xff09;远程库&#xff0c;在本地机器上存储一个完整的Git仓库&#xff0c;还可以把代码的修改提交到本地库…

(专题二)01 矩阵的处理-特殊矩阵

有哪些特殊矩阵&#xff1f; 通用的特殊矩阵 zeros函数 &#xff1a;产生全0矩阵 产生五行五列的随机矩阵A&#xff0c;其值是10--99的整数 产生均值0.6&#xff0c;方差0.1的五行五列正态矩阵B 产生五阶单位阵 验证等式成立 ones函数 &#xff1a;产生全1矩阵 eye函数 &…