[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 ...
随机推荐
- 升级mac的java版本
在OS X EI Capitan下, java版本太低,从oracle官网下载的dmg文件升级一直有问题, 我发现mac下的java环境有三处 #这应该是系统自带java环境,默认/usr/bin/j ...
- WGS84经纬度坐标与web墨卡托之间的转换【转】
第一种方法: //经纬度转Web墨卡托 dvec3 CMathEngine::lonLat2WebMercator(dvec3 lonLat) { dvec3 mercator; ; ); ; mer ...
- Spring Framework jar官方直接下载路径
SPRING官方网站改版后,建议都是通过 Maven和Gradle下载,对不使用Maven和Gradle开发项目的,下载就非常麻烦,下给出Spring Framework jar官方直接下载路径: h ...
- C#中方法的参数修饰符
做项目久了,有的时候真的需要静下心来认真的总结一下自己所用到的技术,而不是每天依葫芦画瓢,每天忙忙碌碌,到头来不知道自己忙了个啥,学了什么,自己到底掌握了多少知识.所以我想回顾一下C#的基础知识,把重 ...
- Javascript基础学习(1)_类型、值和变量
1.null和undefined ①概念上区别: null是一个特殊的对象,是“非对象”,使用typeof后是object对象 undefined用未定义的值表示更深层次的“空值”,它是变量的一种取值 ...
- Windows Azure 试用 for 世纪互联运维
前一段时间申请由世纪互联运维的和谐版Windows Azure的邀请嘛下来,今天花费了点时间注册了一下 注册邀请函, 根据提示输入邀请码之后会收到以下邮件 中国地区可选择建立的虚拟机,SQL Serv ...
- CABasicAnimation添加动画离开屏幕就动画停止的问题
解决方法: animation.removedOnCompletion = NO;
- 【html】【5】html class属性css样式
必看参考: http://www.divcss5.com/css3-style/ http://www.jb51.net/css/142448.html http://www.w3school.com ...
- jQuery仿苏宁易购导航
最近看了些网上的各类导航网站源码,自己学习制作了一个仿苏宁易购的导航栏 jQuery部分代码 $(function(){ $(".CategoryTree>ul>li" ...
- 自定义流程gooflow.08 demo在线演示
一.功能简介 gooflow功能清单1.自定义流程绘制2.自定义属性添加3.支持3种步骤类型 普通审批步骤 自动决策步骤 手动决策步骤 4.决策方式(支持js决策,sql语句决策) 5.审批人员参与方 ...