[LeetCode#212]Word Search II
Problem:
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"]
.
Note:
You may assume that all inputs are consist of lowercase letters a-z
.
Analysis:
This problem is a very typical problem for using DFS. Search on a graph(matrix), find out the path to reach certain goal. At each vertix, we could follow all out edges. Key points:
1. Every gird on the matrix could be treated a start point.
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
searchWord(board, i, j, "", visited, hash_set, ret);
}
}
Before entering the recursive call, we only specify the index(i, j). And only at the recursive funtion, we really add the character at grid(i, j) into our temporary path. This design could have following benefits:
1. When we fork out search branch(left, right, above, below), we don't need to check if the index(i, j) is valid, which could make the code quite concise.
------------------------------------------------------------
searchWord(board, i-1, j, cur_str, visited, hash_set, ret);
searchWord(board, i+1, j, cur_str, visited, hash_set, ret);
searchWord(board, i, j-1, cur_str, visited, hash_set, ret);
searchWord(board, i, j+1, cur_str, visited, hash_set, ret);
-----------------------------------------------------------
To avoid invalid index, we could simplily do it at the beginning of the recursive funtion, when the index was just passed in.
if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || visited[i][j])
return; 2. It is easy to recover changed state(When back tracking).
Let us suppose you change the state before enter the searchWord.
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
visited[i][j] = true;
searchWord(board, i, j, "", visited, hash_set, ret);
visited[i][j] = true;
}
}
To make all changed states could be recovered, you have to do above recover thing for all forked branch.
visited[i-1][j] = true;
searchWord(board, i-1, j, cur_str, visited, hash_set, ret);
visited[i-1][j] = false;
visited[i+1][j] = true;
searchWord(board, i+1, j, cur_str, visited, hash_set, ret);
visited[i+1][j] = false;
visited[i][j-1] = true;
searchWord(board, i, j-1, cur_str, visited, hash_set, ret);
visited[i][j-1] = false;
visited[i][j+1] = true;
searchWord(board, i, j+1, cur_str, visited, hash_set, ret);
visited[i][j+1] = false; How ugly? Right! What'more!!! You need to check is visisted[i][j] is valid for every forked branch.
Sky: Since we do the same recover work for all grid on the matrix, we do not do it together at recursive call? 3. For this DFS problem, each grid could go four directions. To avoid the path back to visited grid, thus result in infinite loop, we should record all gird we have visited.
if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || visited[i][j])
return;
visited[i][j] = true;
check and fork ...
visited[i][j] = false; Since for each grid, we actually search the whole matrix, the search cost is O(m*n).
There are m*n grids in total, Thus the overall time complexity is O(m^2*n^2).
Solution:
public class Solution {
public List<String> findWords(char[][] board, String[] words) {
if (board == null || words == null)
throw new IllegalArgumentException("Plese check the arguments passed into the funtion");
ArrayList<String> ret = new ArrayList<String> ();
if (board.length == 0)
return ret;
HashSet<String> hash_set = new HashSet<String> ();
boolean[][] visited = new boolean[board.length][board[0].length];
for (int i = 0; i < words.length; i++)
hash_set.add(words[i]);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
searchWord(board, i, j, "", visited, hash_set, ret);
}
}
return ret;
} private void searchWord(char[][] board, int i, int j, String cur_str, boolean[][] visited, HashSet<String> hash_set, ArrayList<String> ret) {
if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || visited[i][j])
return;
visited[i][j] = true;
cur_str = cur_str + board[i][j];
if (hash_set.contains(cur_str))
ret.add(cur_str);
searchWord(board, i-1, j, cur_str, visited, hash_set, ret);
searchWord(board, i+1, j, cur_str, visited, hash_set, ret);
searchWord(board, i, j-1, cur_str, visited, hash_set, ret);
searchWord(board, i, j+1, cur_str, visited, hash_set, ret);
visited[i][j] = false;
}
}
[LeetCode#212]Word Search II的更多相关文章
- 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 ...
- [LeetCode] 212. Word Search II 词语搜索 II
Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...
- [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 ...
- leetcode 79. Word Search 、212. Word Search II
https://www.cnblogs.com/grandyang/p/4332313.html 在一个矩阵中能不能找到string的一条路径 这个题使用的是dfs.但这个题与number of is ...
- 【leetcode】212. Word Search II
Given an m x n board of characters and a list of strings words, return all words on the board. Each ...
- 212. Word Search II
题目: Given a 2D board and a list of words from the dictionary, find all words in the board. Each word ...
- 【LeetCode】212. Word Search II 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀树 日期 题目地址:https://leetco ...
- [leetcode trie]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 ...
- 【leetcode】Word Search II(hard)★
Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...
随机推荐
- dhcp源码编译支持4G上网卡
1. tar xvzf dhcp-4.2.5-P1.tar.gz 2. ./configure --host=arm-linux ac_cv_file__dev_random=yes 3. vi bi ...
- Linq扩展方法之Aggregate 对序列应用累加器函数
Linq扩展方法之Aggregate 对序列应用累加器函数; 函数模板:// 函数名:对序列应用累加器函数. // Parameters:参数要求 // source:要聚合的 System.Col ...
- fseek()
原文地址:fseek()作者:xiaoxin 意思是把文件指针指向文件的开头 fseek 函数名: fseek 功 能: 重定位流上的文件指针 用 法: int fseek(FILE *s ...
- Bootstrap-全局css样式之按钮
这里所说的按钮只是Bootstrap设计的能使标签或元素呈现按钮样式的属性,所以为 <a>.<button> 或 <input> 元素添加按钮类(button cl ...
- JS手动创建标签
代码: <html> <head> <title>js标签属性的添加</title> <script > function setxxx() ...
- PHP 内存的分布问题
php运行,内存分为5个区域, 1.基本数据类型--->栈区 2.符合数据类型-->堆区 对象实例在堆区,对象名字在栈区(指向此对象实例的变量)
- 简单的GDI+双缓冲的分析与实现
为什么要使用双缓冲绘制 在进行多图元绘制的时候: 因为是要一个一个画上去,所以每画一个图元,系统就要做一次图形的绘制操作,图形的重绘是很占用资源的,特别当需要重绘的图形数量很多的时候,所造成的消耗就特 ...
- win8.1磁盘使用率100解决方法
关闭家庭组,因为这功能会导致硬盘和CPU处于高负荷状态.关闭方法:Win+C – 设置 – 更改电脑设置 – 家庭组 – 离开如果用不到家庭组可以直接把家庭组服务也给关闭了:控制面板 – 管理工具 – ...
- WPF自定义窗口(Windows Server 2012 Style)
先上图 新建CustomControl,名:HeaderedWindow Themes\Generic.aml文件夹下加入 笔刷,转换器 <SolidColorBrush x:Key=" ...
- HttpWebRequest 写入报错
HttpWebRequest以UTF-8编码写入内容时发生“Bytes to be written to the stream exceed the Content-Length bytes size ...