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.

Hint:

You would need to optimize your backtracking to pass the larger test. Could you stop backtracking earlier?

If the current candidate does not exist in all words' prefix, you could stop backtracking immediately. What kind of data structure could answer such query efficiently? Does a hash table work? Why or why not? How about a Trie? If you would like to learn how to implement a basic trie, please work on this problem: Implement Trie (Prefix Tree) first.

79. Word Search 的拓展,79题是给一个单词让判断是否存在,现在是给了一堆单词,让返回所有存在的单词。

解法:还是用79题的DFS方法,数据结构用字典树Trie

有关字典树的题还有:208. Implement Trie (Prefix Tree) ,  211. Add and Search Word - Data structure design

Java:

public List<String> findWords(char[][] board, String[] words) {
List<String> res = new ArrayList<>();
TrieNode root = buildTrie(words);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs (board, i, j, root, res);
}
}
return res;
} public void dfs(char[][] board, int i, int j, TrieNode p, List<String> res) {
char c = board[i][j];
if (c == '#' || p.next[c - 'a'] == null) return;
p = p.next[c - 'a'];
if (p.word != null) { // found one
res.add(p.word);
p.word = null; // de-duplicate
} board[i][j] = '#';
if (i > 0) dfs(board, i - 1, j ,p, res);
if (j > 0) dfs(board, i, j - 1, p, res);
if (i < board.length - 1) dfs(board, i + 1, j, p, res);
if (j < board[0].length - 1) dfs(board, i, j + 1, p, res);
board[i][j] = c;
} public TrieNode buildTrie(String[] words) {
TrieNode root = new TrieNode();
for (String w : words) {
TrieNode p = root;
for (char c : w.toCharArray()) {
int i = c - 'a';
if (p.next[i] == null) p.next[i] = new TrieNode();
p = p.next[i];
}
p.word = w;
}
return root;
} class TrieNode {
TrieNode[] next = new TrieNode[26];
String word;
}  

Python:

class TrieNode(object):
# Initialize your data structure here.
def __init__(self):
self.is_string = False
self.leaves = {} # Inserts a word into the trie.
def insert(self, word):
cur = self
for c in word:
if not c in cur.leaves:
cur.leaves[c] = TrieNode()
cur = cur.leaves[c]
cur.is_string = True class Solution(object):
def findWords(self, board, words):
"""
:type board: List[List[str]]
:type words: List[str]
:rtype: List[str]
"""
visited = [[False for j in xrange(len(board[0]))] for i in xrange(len(board))]
result = {}
trie = TrieNode()
for word in words:
trie.insert(word) for i in xrange(len(board)):
for j in xrange(len(board[0])):
if self.findWordsRecu(board, trie, 0, i, j, visited, [], result):
return True return result.keys() def findWordsRecu(self, board, trie, cur, i, j, visited, cur_word, result):
if not trie or i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or visited[i][j]:
return if board[i][j] not in trie.leaves:
return cur_word.append(board[i][j])
next_node = trie.leaves[board[i][j]]
if next_node.is_string:
result["".join(cur_word)] = True visited[i][j] = True
self.findWordsRecu(board, next_node, cur + 1, i + 1, j, visited, cur_word, result)
self.findWordsRecu(board, next_node, cur + 1, i - 1, j, visited, cur_word, result)
self.findWordsRecu(board, next_node, cur + 1, i, j + 1, visited, cur_word, result)
self.findWordsRecu(board, next_node, cur + 1, i, j - 1, visited, cur_word, result)
visited[i][j] = False
cur_word.pop() 

C++:

class Solution {
public:
struct TrieNode {
TrieNode *child[26];
string str;
TrieNode() : str("") {
for (auto &a : child) a = NULL;
}
};
struct Trie {
TrieNode *root;
Trie() : root(new TrieNode()) {}
void insert(string s) {
TrieNode *p = root;
for (auto &a : s) {
int i = a - 'a';
if (!p->child[i]) p->child[i] = new TrieNode();
p = p->child[i];
}
p->str = s;
}
};
vector<string> findWords(vector<vector<char> >& board, vector<string>& words) {
vector<string> res;
if (words.empty() || board.empty() || board[0].empty()) return res;
vector<vector<bool> > visit(board.size(), vector<bool>(board[0].size(), false));
Trie T;
for (auto &a : words) T.insert(a);
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[i].size(); ++j) {
if (T.root->child[board[i][j] - 'a']) {
search(board, T.root->child[board[i][j] - 'a'], i, j, visit, res);
}
}
}
return res;
}
void search(vector<vector<char> > &board, TrieNode *p, int i, int j, vector<vector<bool> > &visit, vector<string> &res) {
if (!p->str.empty()) {
res.push_back(p->str);
p->str.clear();
}
int d[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
visit[i][j] = true;
for (auto &a : d) {
int nx = a[0] + i, ny = a[1] + j;
if (nx >= 0 && nx < board.size() && ny >= 0 && ny < board[0].size() && !visit[nx][ny] && p->child[board[nx][ny] - 'a']) {
search(board, p->child[board[nx][ny] - 'a'], nx, ny, visit, res);
}
}
visit[i][j] = false;
}
};

类似题目:

[LeetCode] 79. Word Search 单词搜索

[LeetCode] 208. Implement Trie (Prefix Tree) 实现字典树(前缀树)

  

All LeetCode Questions List 题目汇总

[LeetCode] 212. Word Search II 词语搜索 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 词语搜索之二

    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

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

  4. LeetCode 79. Word Search(单词搜索)

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

  5. [LeetCode] 79. Word Search 单词搜索

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

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

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

  7. 79. 212. Word Search *HARD* -- 字符矩阵中查找单词

    79. Word Search Given a 2D board and a word, find if the word exists in the grid. The word can be co ...

  8. [LeetCode] 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】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 ...

随机推荐

  1. GoLand——配置goproxy.io代理

    前言 由于众所周知的原因,也为了更好的下载go的包,所以找到了goproxy 配置 ctrl+alt+s->Go->Go Modules(vgo)->设置proxy为https:// ...

  2. 【Selenium-WebDriver实战篇】java测试使用HttpClient debug日志关闭

    在上一篇设置完Tess4J之后,引用jar包之前,我的日志体系一直是只出现info级别的,但是引用之后出现很多httpClient的请求. 于是网上调查了下,可以通过代码实现,就在入口程序增加该部分代 ...

  3. AST11103 Problem Solving

    AST11103 Problem Solving with Programming SkillsAdditional Individual Assignment: Min-Game Programmi ...

  4. super()函数

    1.简单的使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: 在上面,A ...

  5. 一个Tomcat下部署多个项目异常:org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean 的解决方法

    内容简介 在测试服务器上Tomcat下部署两个Spring boot项目,总是一个能启动成功,另一个启动不成功.这两个war包单独部署均能正常启动. 查看日志:启动时报出 org.springfram ...

  6. 学习:C++中的头文件和源文件详解

    一.C++编译模式: 通常,在一个C++程序中,只包含两类文件――.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是 ...

  7. JSON和计算机网络的个人总结

    JSON JSON是什么? JSON:JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于ECMAScript (欧洲计算机协会制定的js规范) ...

  8. The database returned no natively generated identity value错误解决方案

    原因:hibernate项目中在学生表的配置文件中: <id name="studentno" column="studentno"> <ge ...

  9. The two of the oldest man need cheers

    At a company dinner, the drinking rule was that two colleagues of similar age clinked glasses of win ...

  10. Flutter 简介(事件、路由、异步请求)

    1. 前言 Flutter是一个由谷歌开发的开源移动应用软件开发工具包,用于为Android和iOS开发应用,同时也将是Google Fuchsia下开发应用的主要工具.其官方编程语言为Dart. 同 ...