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"].

思路:

好奇怪啊,我自己写了一个DFS的代码,这种TLE。网上看看发现要用字典树,其实就是把查询给定字符串的过程简化了。

可是我的代码也查询的很容易啊。为什么我的代码TLE,字典树代码就只要56ms呢?

字典数Trie代码:其中标记使用过字符的方式值得学习

class Solution2 {
class Trie{
public:
Trie *children[]; //指向其子序列 从'a'到'z'
bool leaf; //该结点是否是叶子结点
int idx; //如果该节点是叶子结点, idx是该单词在vector中的序号
Trie()
{
this->leaf = false;
this->idx = ;
fill_n(this->children, , nullptr);
}
}; public:
void insertWords(Trie *root, vector<string>& words, int idx)
{
int pos = , len = words[idx].size();
while(pos < len)
{
if(NULL == root->children[words[idx][pos] - 'a'])
root->children[words[idx][pos] - 'a'] = new Trie();
root = root->children[words[idx][pos++] - 'a'];
}
root->leaf = true;
root->idx = idx;
} Trie * buildTrie(vector<string>& words)
{
Trie * root = new Trie();
for(int i = ; i < words.size(); ++i)
insertWords(root, words, i);
return root;
} void checkWords(vector<vector<char>>& board, int i, int j, int row, int col, Trie *root, vector<string> &res, vector<string>& words)
{
if(i < || j < || i >= row || j >= col) return;
if(board[i][j] == 'X') return; //已经访问过
if(NULL == root->children[board[i][j] - 'a']) return;
char temp = board[i][j];
if(root->children[temp - 'a']->leaf) //这是叶子结点
{
res.push_back(words[root->children [temp - 'a']->idx]);
root->children[temp - 'a']->leaf = false; //标为false表示已经找到之歌单词了
}
board[i][j] = 'X'; //标记这个字母为已找过 checkWords(board, i-, j, row, col, root->children[temp-'a'], res, words);
checkWords(board, i+, j, row, col, root->children[temp-'a'], res, words);
checkWords(board, i, j-, row, col, root->children[temp-'a'], res, words);
checkWords(board, i, j+, row, col, root->children[temp-'a'], res, words); board[i][j] = temp;
} vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
vector<string> res;
int row = board.size();
if(==row) return res;
int col = board[].size();
if(==col) return res;
int wordCount = words.size();
if(==wordCount) return res; Trie *root = buildTrie(words); int i,j;
for(i = ; i<row; i++)
{
for(j=; j<col && wordCount > res.size(); j++)
{
checkWords(board, i, j, row, col, root, res, words);
}
}
return res;
} };

我自己的代码:

class Solution {
public:
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
if(board.empty()) return vector<string>(); vector<string> ans;
//对所有入口遍历
for(int i = ; i < board.size(); ++i)
{
for(int j = ; j < board[].size(); ++j)
{
string scur;
unordered_set<int> myset;
getAnswer(i, j, board, words, scur, ans, myset);
}
}
return ans;
} void getAnswer(int i, int j, vector<vector<char>>& MyBoard, vector<string> ResWords, string scur, vector<string>& ans, unordered_set<int> myset)
{
if(ResWords.empty()) return; //没有更多的单词
if(i < || j < || i >= MyBoard.size() || j >= MyBoard[].size()) return;
if(myset.find(i * MyBoard[].size() + j) != myset.end()) return; //该字母已经使用过
myset.insert(i * MyBoard[].size() + j);
vector<string> newResWords;
//对所有剩下待匹配的单词(即前面字母都符合,并且没有完全匹配的单词)
for(int k = ; k < ResWords.size(); ++k)
{
if(MyBoard[i][j] == ResWords[k][scur.length()] && ResWords[k].length() == scur.length() + ) //新字母与单词匹配 且单词没有更多的字母 压入答案
ans.push_back(scur + MyBoard[i][j]);
else if(MyBoard[i][j] == ResWords[k][scur.length()]) //若字母匹配 压入新的剩余单词
newResWords.push_back(ResWords[k]);
}
scur += MyBoard[i][j]; getAnswer(i + , j, MyBoard, newResWords, scur, ans, myset);
getAnswer(i - , j, MyBoard, newResWords, scur, ans, myset);
getAnswer(i, j + , MyBoard, newResWords, scur, ans, myset);
getAnswer(i, j - , MyBoard, newResWords, scur, ans, myset);
}
};

【leetcode】Word Search II(hard)★的更多相关文章

  1. 【leetcode】Word Ladder II

      Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation ...

  2. 【leetcode】Word Break II

    Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...

  3. 【leetcode】Word Search

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

  4. 【leetcode】Word Search (middle)

    今天开始,回溯法强化阶段. Given a 2D board and a word, find if the word exists in the grid. The word can be cons ...

  5. 【leetcode】Word Break II (hard)★

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  6. 【leetcode】Word Ladder II(hard)★ 图 回头看

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

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

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

  9. 【LeetCode】47. Permutations II 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:回溯法 日期 题目地址:htt ...

随机推荐

  1. 浏览器内核与js引擎

    摘要: 面试一个大公司的时候问到了一个问题,让我谈谈主要的浏览器内核以及他们的特点,当时并没有详细的回答,回来之后自己在网上找了找资料,总结了下分享给大家. 简介: 在维基百科上是这样介绍浏览器内核的 ...

  2. PHP CLI下接受参数的几种方法

    PHP CLI(命令行模式下)接受参数有多种方法: (1)使用$argv接受参数 <?php //变量仅在 register_argc_argv 打开时可用. print_r($argc); / ...

  3. Ubuntu 14 添加Windows风格的底部任务栏

    习惯了Windows风格的底部任务栏,而Ubuntu 14是没有的,还好有人做好了一个任务栏插件,可以在线安装: 1.打开终端(Ctrl+Alt+T),然后输入下面的命令 sudo apt-get i ...

  4. JVM初探 -JVM内存模型

    JVM初探 -JVM内存模型 标签 : JVM JVM是每个Java开发每天都会接触到的东西, 其相关知识也应该是每个人都要深入了解的. 但接触了很多人发现: 或了解片面或知识体系陈旧. 因此最近抽时 ...

  5. android service被系统回收的解决方法

    自己的app的service总是容易被系统回收,搜罗了一下,基本上的解决思路有以下几种: 1.把service写成系统服务,将永远不会被回收(未实践): 在Manifest.xml文件中设置persi ...

  6. BZOJ1212——L语言

    题目大意:每一个字符串都可以分解成一些个单词组成,现在给你一些单词,再给你一个字符串, dp吧,设f[i]为从0开始,到i结束的字符串前缀是否可以被分解,因为单词长度很小,所以,这就T了, (什么逻辑 ...

  7. .net获取周几(中文)

    DateTime.Now.ToString("yyyy年MM月dd日 星期ddd hh时mm分ss秒", new System.Globalization.CultureInfo( ...

  8. UIView动画效果

    做出UI界面,实现程序功能,是重中之重,但是通过动画提升使用体验,一般人应该不会拒绝吧. 那么问题又来了,怎么做? 一: 稳扎稳打: 一步一步来吧,毕竟,心急吃不了热豆腐. 1.开启一个动画 2,设置 ...

  9. 初识Flask

    首先在学习flask的前提,我是使用了很久的django和tornado,现在在写总结也是本着工作后方便使用flask 少点东西,对flask的介绍和优点总结 1.安装 pip install fla ...

  10. jQuery工作原理

    jQuery的开篇声明里有一段非常重要的话:jQuery是为了改变javascript的编码方式而设计的.从这段话可以看出jQuery本身并不是UI组件库或其他的一般AJAX类库.jQuery改变ja ...