写在前面:这两周持续看花花酱整理的题目列表和视频讲解,也得益于自己持续多年刷题,今天刷这道题目的想法是:会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(m∗n∗4l),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;}}
}

212. Word Search II:多个单词查找相关推荐

  1. 【DFS + Backtracking】LeetCode 212. Word Search II

    LeetCode 212. Word Search II Solution1:我的答案 暴力搜索..基于第79题的答案,真的是非常之慢啊!!! 快的方法均是基于字典树的方法,真是复杂.. class ...

  2. leetcode 212. Word Search II | 212. 单词搜索 II(Trie,回溯,DFS)

    题目 https://leetcode.com/problems/word-search-ii/ 题解 基于前缀树实现,如果把 Trie 也看做一个特殊的图的话,就是 将两个图同时进行 dfs,就像判 ...

  3. [Leetcode] 212. Word Search II 解题报告

    题目: Given a 2D board and a list of words from the dictionary, find all words in the board. Each word ...

  4. 【lintcode】树形数据结构之Maxtree, Tree iterator, remove bst node, 优先队列之动态中位数Median, 矩阵dfs之word search II,最大连

    解析 max ksubarray sum:  最大和 of 连续子序列 =>   最大和 of  k份连续子序列 属于dp,30行代码搞定,注意一些边界. substr diff:  无queu ...

  5. [Swift]LeetCode212. 单词搜索 II | Word Search II

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  6. LeetCode() Word Search II

    超时,用了tire也不行,需要再改. class Solution {class TrieNode { public:// Initialize your data structure here.Tr ...

  7. 【CODE】Unique Paths Word Search (DFS dp 字典树)

    目录 62. Unique Paths 63. Unique Paths II 980. Unique Paths III 79. Word Search 212. Word Search II 字典 ...

  8. LeetCode 79. Word Search

    原题链接在这里:https://leetcode.com/problems/word-search/ 题目: Given a 2D board and a word, find if the word ...

  9. 数据结构 单词查找 二分法-索引表-Hash表

    问题说明: 从标准输入中读入一个英文单词及查找方式,在一个给定的英文常用单词字典文件dictionary3000.txt中查找该单词,返回查找结果(查找到返回1,否则返回0)和查找过程中单词的比较次数 ...

最新文章

  1. 编译android系统小结
  2. python集合属性方法运算_Python基础__字典、集合、运算符
  3. 【算法】Logistic原理
  4. 新冠肺炎的可视化和预测分析(附代码)
  5. Python--三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数...
  6. iptables (2) 基本配置
  7. python单例模式继承_Python四种实现单例模式的方法
  8. Python是什么?Python能干什么?一篇文章让你对Python了如指掌!!
  9. 一个测试新人的职业规划——三个月
  10. Pentium 4处理器架构/微架构/流水线 (7) - NetBurst前端详解 - 分支预测
  11. 火遍全网,却被广东人嫌弃!昔日“百亿网红”,快被打回原形了
  12. R语言使用strsplit函数按照指定的分隔符号进行数据拆分、分裂(split)、分割后的数据类型为列表
  13. 数据分析学习总结笔记06:T检验的原理和步骤
  14. react前端显示图片_react.js - 关于react引用本地静态资源图片的问题
  15. 关于sac的一些笔记
  16. php 获取header头信息并显示网址,php 获取远程网址header头信息的方法
  17. iOS 架构模式 - 简述 MVC, MVP, MVVM
  18. 2022小米运维开发笔试1
  19. 图灵对计算机行业的贡献论文,这届图灵奖得主究竟做了什么贡献?这篇1974年的论文给了我们答案...
  20. 查一下服务器的系统,如何查看服务器的操作系统

热门文章

  1. jquery通过attr取html里自定义属性原来这么方便啊
  2. GDB调试程序(二)
  3. zoj 1366 Cash Machine
  4. SharePoint【学习笔记】-- SharePoint 2010 技术参数整理
  5. SQL Tree解法
  6. IXMLDOMDocument中的load方法返回值有BUG
  7. rust房屋建造蓝图_都说蓝图,而不是白图、红图,你知道为什么?
  8. 《Java并发编程实践-第一部分》-读书笔记
  9. eclipse搜索框太小
  10. maven jar包冲突的发现与解决[工具篇]