【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 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)★的更多相关文章
- 【leetcode】Word Ladder II
Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation ...
- 【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 ...
- 【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 ...
- 【leetcode】Word Search (middle)
今天开始,回溯法强化阶段. Given a 2D board and a word, find if the word exists in the grid. The word can be cons ...
- 【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 ...
- 【leetcode】Word Ladder II(hard)★ 图 回头看
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...
- 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】47. Permutations II 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:回溯法 日期 题目地址:htt ...
随机推荐
- 存储过程获取最后插入到数据表里面的ID
存储过程获取最后插入到数据表里面的ID SET NOCOUNT on;---不返回影响行数提高性能GOcreate proc [sp_bbs_thread_Insert] @id int output ...
- codevs2171 棋盘覆盖
题目描述 Description 给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖. 输入描述 Input Description 第一 ...
- 金山毒霸和Chrome浏览器植入脚本导致网页报错
1 (function(win, undefined) { var SELECTORS = transformSelector; function insertTemplate(callback) { ...
- box-sizing属性
我们都知道,设置元素的padding或者margin属性时都会改变元素的width和height,传统的方法是将padding和margin的值考虑进去,运用数学的方法进行计算来加以调整,以便使布局不 ...
- PHP Closure类Bind与BindTo方法
Closure类为闭包类,PHP中闭包都是Closure的实例: 1 $func = function(){}; 2 var_dump($func instanceof Closure); 输出 bo ...
- laravel路由基础
基础: 所有的laravel路由都定义在 app/Http/routes.php 这个文件里,会被框架自带加载.简单的路由会接受一个URI和一个Closure类. Route::get('foo', ...
- android 弹出的软键盘遮挡住EditText文本框的解决方案
1.android 弹出的软键盘遮挡住EditText文本框的解决方案: 把Activit对应的布局文件filename.xml文件里的控件用比重设置布局.(例如:android:layout_wei ...
- Linux文件读写机制及优化方式
导读 Linux是一个可控性强的,安全高效的操作系统.本文只讨论Linux下文件的读写机制,不涉及不同读取方式如read,fread,cin等的对比,这些读取方式本质上都是调用系统api read,只 ...
- tab切换,滑动门
<SCRIPT type=text/javascript> jQuery(document).ready(function () { changediv([" ...
- 160809212田京诚C语言程序设计实验2 选择结构程序设计_进阶
实验2-6 猜数字游戏 实验要求: 编写一个C程序实现一个[1-100]以内的猜数字游戏. (1) 系统随机产生一个[1-100]之间的随机数. (2) 输入任意一个数字.数字 ...