Java实现 LeetCode 212 单词搜索 II(二)
212. 单词搜索 II
给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例:
输入:
words = ["oath","pea","eat","rain"] and board =
[
['o','a','a','n'],
['e','t','a','e'],
['i','h','k','r'],
['i','f','l','v']
]
输出: ["eat","oath"]
说明:
你可以假设所有输入都由小写字母 a-z 组成。
提示:
你需要优化回溯算法以通过更大数据量的测试。你能否早点停止回溯?
如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。什么样的数据结构可以有效地执行这样的操作?散列表是否可行?为什么? 前缀树如何?如果你想学习如何实现一个基本的前缀树,请先查看这个问题: 实现Trie(前缀树)。
PS:
首先构建一个字典树,然后在dfs的时候加入字典树,以某个字符串结尾的可以减少搜索次数
这里为什么不用开头用结尾呢, (●ˇ∀ˇ●)
结尾在这里就是我搜索完一个,我可以直接比较,如果没有的话,我再返回上一个,
class TrieNode {
private static final int ALPHABET_SIZE = 26;
TrieNode[] children = new TrieNode[ALPHABET_SIZE];
// 判断这个前缀是不是某个字符串的结尾
boolean isEndOfWord = false;
TrieNode() {
isEndOfWord = false;
for (int i = 0; i < ALPHABET_SIZE; i++)
children[i] = null;
}
}
class Trie {
public TrieNode root;
/** Initialize your data structure here. */
public Trie() {
root = new TrieNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode curNode = root;
int index;
for (int i = 0; i < word.length(); i++) {
index = word.charAt(i) - 'a';
if (curNode.children[index] == null) {
curNode.children[index] = new TrieNode();
}
curNode = curNode.children[index];
}
curNode.isEndOfWord = true;
}
}
class Solution {
public List<String> findWords(char[][] board, String[] words) {
List<String> result = new ArrayList<>();
if (words == null || words.length == 0 || board == null || board.length == 0 || board[0].length == 0)
return result;
Trie trie = new Trie();
for (String temp : words)
trie.insert(temp);
TrieNode root = trie.root;
boolean[][] visited = new boolean[board.length][board[0].length];
Set<String> tempResult = new HashSet<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (root.children[board[i][j] - 'a'] != null ) {
dfs(board, visited, i, j, root.children[board[i][j] - 'a'], tempResult, sb);
}
}
}
// 需要把tempResult这个set拷贝到真正的result List中进行返回
Iterator<String> iterator = tempResult.iterator();
while (iterator.hasNext()) {
result.add(iterator.next());
}
return result;
}
private void dfs(char[][] board, boolean[][] visited, int startIInBoard, int startJInBoard
, TrieNode curNode, Set<String> resultSet, StringBuilder curStrBuilder) {
curStrBuilder.append(board[startIInBoard][startJInBoard]);
visited[startIInBoard][startJInBoard] = true;
if (curNode.isEndOfWord) {
resultSet.add(curStrBuilder.toString());
}
// 向上搜索, 如果上面的格子没有被搜索过的话
if (startIInBoard > 0 && !visited[startIInBoard - 1][startJInBoard]
&& curNode.children[board[startIInBoard - 1][startJInBoard] - 'a'] != null) {
dfs(board, visited,startIInBoard - 1, startJInBoard
, curNode.children[board[startIInBoard - 1][startJInBoard] - 'a'], resultSet, curStrBuilder);
}
// 向下搜索
if (startIInBoard < board.length - 1 && !visited[startIInBoard + 1][startJInBoard]
&& curNode.children[board[startIInBoard + 1][startJInBoard] - 'a'] != null) {
dfs(board, visited,startIInBoard + 1, startJInBoard
, curNode.children[board[startIInBoard + 1][startJInBoard] - 'a'], resultSet, curStrBuilder);
}
// 向左搜索
if (startJInBoard > 0 && !visited[startIInBoard][startJInBoard - 1]
&& curNode.children[board[startIInBoard][startJInBoard - 1] - 'a'] != null) {
dfs(board, visited, startIInBoard, startJInBoard - 1
, curNode.children[board[startIInBoard][startJInBoard - 1] - 'a'], resultSet, curStrBuilder);
}
// 向右搜索
if (startJInBoard < board[0].length - 1 && !visited[startIInBoard][startJInBoard + 1]
&& curNode.children[board[startIInBoard][startJInBoard + 1] - 'a'] != null) {
dfs(board, visited, startIInBoard, startJInBoard + 1
, curNode.children[board[startIInBoard][startJInBoard + 1] - 'a'], resultSet, curStrBuilder);
}
// 恢复现场
curStrBuilder.setLength(curStrBuilder.length() - 1);
visited[startIInBoard][startJInBoard] = false;
}
}
Java实现 LeetCode 212 单词搜索 II(二)的更多相关文章
- Java实现 LeetCode 212 单词搜索 II
public class Find2 { public int[] dx={1,-1,0,0}; public int[] dy={0,0,1,-1}; class Trie{ Trie[] trie ...
- [leetcode] 212. 单词搜索 II(Java)
212. 单词搜索 II 这leetcode的评判机绝对有问题!!同样的代码提交,有时却超时!害得我至少浪费两个小时来寻找更优的答案= =,其实第一次写完的代码就可以过了,靠!!!第207位做出来的 ...
- [LeetCode] 212. 单词搜索 II
题目链接:https://leetcode-cn.com/problems/word-search-ii/ 题目描述: 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在 ...
- Leetcode 212.单词搜索II
单词搜索II 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻&q ...
- Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)
Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...
- Java实现 LeetCode 140 单词拆分 II(二)
140. 单词拆分 II 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中.返回所有这些可能的句子. 说明: 分 ...
- Java for 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 mus ...
- Java实现 LeetCode 79 单词搜索
79. 单词搜索 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格. ...
- 212. 单词搜索 II
Q: 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻" ...
随机推荐
- R语言:计算现金工资的币数
新入职的员工,有的没有相应银行卡,需要计算现金工资的币数.实发工资,一般取整数. 简化计算,纸币面值只有100.10.1.4278除以100等于42余78,78除以10等于7余8,8除以1等于8. 复 ...
- 对文本的内容进行排序(io流、集合操作)
package com.itheima.demo01.BufferedStream; import java.io.*; import java.util.HashMap; /* 练习: 对文本的内容 ...
- 帝国cms列表页内容简介字段smalltext去除里面html格式代码 设置方法
帝国cms列表页内容简介字段smalltext去除里面html格式代码帝国cms列表页调用内容简介出现html代码怎么办 近来在用帝国cms的时候,发现一个问题,在列表页调用产品简介的时候出现了这种h ...
- springData表关系:一对一
一.编写两个实体类 1.一对一关系实现:a:使用外键关联 b:使用主键关联,两个表的主键相同 2.外键方案:配置关联关系:两个实体类互相关联,并且在关联的属性上添加一个@OneToOne代表一个对一个 ...
- vue实例中created、mounted以及其他类型说明
生命周期图示(图片来自coderwhy老师): 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后 ...
- jmeter学习之安装篇(一)
一.Jmeter简介 Jmeter是Apache组织开发的基于Java开源项目,设计之初是用于做性能测试的,同时它在实现对各种接口的调用方面做的比较成熟,因此,常被用做接口功能测试和性能测试. Jme ...
- vuecli3.x与vuecli2.x 主要区别
3.0 新加入了 TypeScript 以及 PWA 的支持 部分命令发生了变化: 下载安装 npm install -g vue@cli 删除了vue list 创建项目 vue create ...
- HTML使用正则验证
制作HTML前台用户验证等,需要对用户名或者密码进行验证,这时使用正则表达式能够精确地对text进行限制. 具体在HTML中的运用代码如下: 转自 https://blog.csdn.net/weix ...
- Python创建一个简单的区块链
区块链(Blockchain)是一种分布式账本(listributed ledger),它是一种仅供增加(append-only),内容不可变(immutable)的有序(ordered)链式数据结构 ...
- [PHP学习教程 - 网络]003.获得当前访问的页面URL(Current Request URL)
引言:获取当前请求的URL路径,自动判断协议(HTTP or HTTPS). 一句话的事情,下面直接上高清无MSK的精妙代码! 功能函数 获得当前请求的页面路径(URL)地址 语法:$url = ge ...