LeetCode212. Word Search II
来源:互联网 发布:应知故乡事的前一句 编辑:程序博客网 时间:2024/06/06 05:56
LeetCode212. Word Search II
问题描述
Given a 2D board and a list of words from the dictionary, find all words in the board.
Each word must be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
For example,
Given words =["oath","pea","eat","rain"]
and board =
[
['o','a','a','n'],
['e','t','a','e'],
['i','h','k','r'],
['i','f','l','v']
]Return
["eat","oath"]
.
问题分析
问题是给定一个String数组,判断数组内的字符串是否能够在字符表中字符组成。比如eat可以由e(1,3),a(1,2),t(1,1)
这三个元素组成。我们可以把这个表看作是图中节点的关联矩阵。那么就是建立节点坐标,然后对每个字符串从头到尾进行匹配就可以了。
代码如下
Java代码
public List<String> findWords(char[][] board, String[] words) { List<int []>[] boardNode = new List[26]; //获取board行列 int m = board.length,n = board[0].length; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int b = board[i][j]-'a'; if(boardNode[b]==null){ boardNode[b]=new ArrayList<>(); } boardNode[b].add(new int[]{i,j}); } } Set<String> res= new HashSet<>(); for (String word:words ) { if(boardNode[word.charAt(0)-'a']!=null){ for (int[] child: boardNode[word.charAt(0)-'a'] ) { if(search(word,0,board,child[0],child[1],new boolean[m][n])){ res.add(word); break; } } } } return new ArrayList<>(res); } boolean search(String word,int index,char[][] board,int i,int j, boolean visited[][]){ //如果当前单元格已经完成 if(index==word.length()) return true; //如果越界或者当前单元格已经访问过,返回False if(i==board.length||i<0) return false; if(j==board[0].length||j<0) return false; if(visited[i][j]) return false; if(word.charAt(index)==board[i][j]){ //如果当前单元格符合要求 visited[i][j]=true; //继续递归 if(search(word,index+1,board,i+1,j,visited)||search(word,index+1,board,i-1,j,visited) || search(word,index+1,board,i,j+1,visited)|| search(word,index+1,board,i,j-1,visited)) return true; visited[i][j]=false; } return false; }
Java代码改进
因为上述代码的运行时间太差了,应该怎么优化呢。上述代码因为对所有的字符串都进行完整的判断,如果出现两个重复的字符串asdasd
,asdasd
那么仍然会完成两个递归,如果俩个字符串由大量的相同部分。asdasdfff
,asdasdeee
,也会完成两个递归,这样会浪费大量的时间,那么如何对上述算法进行优化呢。我们之前所写的Trie类型就起到了作用,将字符串数组表达为Trie树结构。对这个Trie树进行判断,这样重复的部分就只需要进行一次递归就行了。
在递归过程中,如果发现符合条件的字符串就添加到结果中
public List<String> findWords(char[][] board, String[] words) { List<String> res = new ArrayList<>(); TrieNode root = buildTrieNode(words); for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { dfs(board, i, j, root, res,new StringBuilder()); } } return res;}void dfs(char[][] board,int i,int j,TrieNode trieNode,List<String> res,StringBuilder stringBuilder){ char c = board[i][j]; int ci = c-'a'; //如果当前board已被使用或者不符合trie树的结构 if(c=='#'||trieNode.children[ci]==null) return; trieNode = trieNode.children[ci]; stringBuilder.append(c); if(trieNode.isEnd){ res.add(stringBuilder.toString()); trieNode.isEnd =false; } board[i][j]='#'; if(i>0) dfs(board,i-1,j,trieNode,res,stringBuilder); if(j>0) dfs(board,i,j-1,trieNode,res,stringBuilder); if(j+1<board[0].length) dfs(board,i,j+1,trieNode,res,stringBuilder); if(i+1<board.length) dfs(board,i+1,j,trieNode,res,stringBuilder); stringBuilder.deleteCharAt(stringBuilder.length()-1); board[i][j]=c;}TrieNode buildTrieNode(String[] words){ TrieNode root = new TrieNode(); TrieNode node ; for (String word:words ) { node=root; for (int i = 0; i < word.length(); i++) { int c= word.charAt(i)-'a'; if(node.children[c]==null) node.children[c]= new TrieNode(); node = node.children[c]; } node.isEnd=true; } return root;}class TrieNode{ TrieNode[] children = new TrieNode[26]; boolean isEnd = false;}
LeetCode学习笔记持续更新
GitHub地址 https://github.com/yanqinghe/leetcode
CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678
- leetcode212:Word Search II
- Leetcode212-Word Search II
- [LeetCode212] Word Search II
- LeetCode212. Word Search II
- LeetCode Word Search II
- [leetcode] Word Search II
- LeetCode Word Search II
- leetcode Word Search II
- Word Search II
- Word Search II
- LeetCode - Word Search II
- Word Search II
- [leetcode]Word Search II
- word search II
- Word Search II
- leetcode Word Search II
- Leetcode -- Word Search II
- LeetCode Word Search II
- 1874 字符串排序 (逆序对)
- LinkedList<HashMap<String, Integer>> students = new LinkedList<HashMap<String, Integer>>();
- java设计模式之单例,工厂,代理模式
- 索引概述
- C语言之贪心算法
- LeetCode212. Word Search II
- Kotlin发迹史
- MarchingCube实现(C++ OpenGl代码篇)
- opencv 图像识别程序
- C++
- thymleaf基础
- Java面试题准备
- 创建ROS项目并添加第三方库(curl)进行网络请求
- AI担任法庭“书记员”,法律行业是否将因AI发生巨变?