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的更多相关文章

  1. 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 ...

  2. [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 ...

  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 mus ...

  4. leetcode 79. Word Search 、212. Word Search II

    https://www.cnblogs.com/grandyang/p/4332313.html 在一个矩阵中能不能找到string的一条路径 这个题使用的是dfs.但这个题与number of is ...

  5. 【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 ...

  6. 212. Word Search II

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

  7. 【LeetCode】212. Word Search II 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀树 日期 题目地址:https://leetco ...

  8. [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 ...

  9. 【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 ...

随机推荐

  1. Modem常用概念

    真实设备的标识,即DEVICE_ID.比如,Android设备是手机,这个DEVICE_ID可以同通过TelephonyManager.getDeviceId()获取,它根据不同的手机设备返回IMEI ...

  2. asp gridview批量删除和全选

    本人新手刚学asp.net   全选和删除也是引用了他人的代码试了一试可以实现,感觉很好,就发了上来. 前台代码 <asp:GridView ID="GridView1" r ...

  3. 利用Inltellj创建javadoc ,用jd2chm创建chm

    现在有些框架都不带javadoc 就需要自己去生成,而且真正用起来还是chm的最方便,所以写篇日志记录一下 下面我就拿struts2的源码来来举个栗子 1.第一步:创建一个空的java项目,导入框架源 ...

  4. html语言中的meta元素

    1.定义语言  格式:〈meta http-equiv=″Content-Type″ content=″text/html; charset=gb2312″〉  这是META最常见的用法,在制作网页时 ...

  5. python基础知识二

    对象 python把在程序中用到的任何东西都成为对象. 每一个东西包括数.字符串甚至函数都是对象. 使用变量时只需要给他们赋一个值.不需要声明或定义数据类型. 逻辑行与物理行 物理行是你在编写程序时所 ...

  6. Java 非对称加密

    package test; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.Object ...

  7. MongoDB的安装和基本操作

    一.使用前的准备(windows下的安装)  1.下载 目前MongoDB的官网不知道问什么不能进行下载了,但是可以在MongoDB中文论坛进行下载, 地址如下:http://www.mongoing ...

  8. HTML中的API

    在程序语言里面就使用API这个行为来讲,可拆解为两个操作:取得API接口和运行API功能 例如:书本具有传授知识的功能,这里就好比一个API,学生拿出某个课本学习,就相当于取得API,学习通过课本学习 ...

  9. js - get-the-value-from-the-url-parameter(可以在非模态对话框中使用)

    ref: http://stackoverflow.com/questions/979975/how-to-get-the-value-from-the-url-parameter 函数: funct ...

  10. css - div垂直方向滚动

    只要设置 OVERFLOW-Y:auto;OVERFLOW-X:hidden即可.