Given an m x n board of characters and a list of strings words, return all words on the board. Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
     这个题目相比于word search来说不是对一个word进行检索,而是对多个word 进行检索,可以对在79题目的基础上进行修改 ,增加一个循环,得到一个基本的解法,但是时间复杂度较高,没法oc
class Solution {
public:
bool dfs(vector<vector<char>>& board,string word,int i,int j,int n){
//递归终止条件
if(n==word.size()) return true;
if(i<0 || j<0 || i>=board.size()||j>=board[0].size() || board[i][j]!=word[n]) return false;
board[i][j]='0';//这个位置检索到了
bool flag=(dfs(board,word,i+1,j,n+1) || dfs(board,word,i-1,j,n+1)||
dfs(board,word,i,j+1,n+1)|| dfs(board,word,i,j-1,n+1));
board[i][j]=word[n];
return flag;
}
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
//word search plus版本 word search 是检索一个word 这个版本是每个word都进行检索
// 一个单词一个单词的去检索
int m=board.size(),n=board[0].size();
vector<string>res;
for(auto word:words){
for(int i=0;i<m;++i){
for(int j=0;j<n;++j){
if(dfs(board,word,i,j,0)){
res.push_back(word);
i=m;
j=n;//跳出循环
}
}
}
}
return res;
}
};
  如何优化这个题目呢,能不能并发的对多个word同时进行检索呢? 通过字典树来实现快速查询。
class Solution {
int dir[5]={1,0,-1,0,1};//检索方向
public:
//嵌套类 构建一个前缀树
class Trie{ public:
string s;
Trie *next[26]; public: Trie() {
s="";
memset(next,0,sizeof(next));//初始化多叉树的索引
} void insert(string word){
Trie *node=this;
for(auto ww:word){
if(node->next[ww-'a']==NULL){
node->next[ww-'a']=new Trie();
}
node=node->next[ww-'a'];
}
node->s=word;
}
}; vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
vector<string> res;
if(board.size()==0 || board[0].size()==0 || words.size()==0) return res;
vector<vector<bool>> dp(board.size(),vector<bool>(board[0].size(),false));
Trie *T=new Trie();
for(auto word:words){
T->insert(word);
}
for(int i=0;i<board.size();++i){
for(int j=0;j<board[0].size();++j){
if(T->next[board[i][j]-'a']!=NULL){
search(board,T->next[board[i][j]-'a'],i,j,dp,res);
}
}
}
return res;
}
void search(vector<vector<char>>& board, Trie* p, int i, int j, vector<vector<bool>>& dp, vector<string>& res) {
if (!p->s.empty()) {
res.push_back(p->s);
p->s.clear();
}
dp[i][j] = true;
for (int ii=0;ii<4;++ii) {
int nx = i + dir[ii], ny = j + dir[ii+1];
if (nx >= 0 && nx < board.size() && ny >= 0 && ny < board[0].size() && !dp[nx][ny] && p->next[board[nx][ny] - 'a']) {
search(board, p->next[board[nx][ny] - 'a'], nx, ny, dp, res);
}
}
dp[i][j] = false;
}
};
  同样也可以用结构体来构建一个前缀树:
class Solution {
public:
struct TrieNode {
TrieNode *child[26];
string str;
};
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】212. Word Search II的更多相关文章

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

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

  2. 【LeetCode】79. Word Search

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

  3. 【LeetCode】140. Word Break II

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

  4. 【LeetCode】140. Word Break II 解题报告(Python & C++)

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

  5. 【LeetCode】79. Word Search 解题报告(Python & C++)

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

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

  7. 【leetcode】126. Word Ladder II

    题目如下: 解题思路:DFS或者BFS都行.本题的关键在于减少重复计算.我采用了两种方法:一是用字典dic_ladderlist记录每一个单词可以ladder的单词列表:另外是用dp数组记录从star ...

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

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

  9. 【LeetCode】Longest Word in Dictionary through Deleting 解题报告

    [LeetCode]Longest Word in Dictionary through Deleting 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode. ...

随机推荐

  1. Go 日常开发常备第三方库和工具

    不知不觉写 Go 已经快一年了,上线了大大小小好几个项目:心态也经历了几轮变化. 因为我个人大概前五年时间写的是 Java ,中途写过一年多的 Python,所以刚接触到 Go 时的感觉如下图: 既没 ...

  2. seq2seq之双向解码

    目录 背景介绍 双向解码 基本思路 数学描述 模型实现 训练方案 双向束搜索 代码参考 思考分析 文章小结 在文章<玩转Keras之seq2seq自动生成标题>中我们已经基本探讨过seq2 ...

  3. 一文搞懂js中的typeof用法

    基础 typeof 运算符是 javascript 的基础知识点,尽管它存在一定的局限性(见下文),但在前端js的实际编码过程中,仍然是使用比较多的类型判断方式. 因此,掌握该运算符的特点,对于写出好 ...

  4. 使用silky脚手架构建微服务应用

    目录 模板简介 构建独立应用的模板Silky.App.Template 构建模块化应用的模板Silky.Module.Template 开源地址 在线文档 模板简介 使用 dotnet new 命令可 ...

  5. Linux常用命令和快捷键整理:(2)常用快捷键

    前言: Linux常用快捷键和基本命令整理,先上思维导图: linux常用命令请见:https://www.cnblogs.com/yinzuopu/p/15516499.html 基本快捷键的使用 ...

  6. 菜鸡的Java笔记 第二十四 - java 接口的基本定义

    1.接口的基本定义以及使用形式        2.与接口有关的设计模式的初步认识        3.接口与抽象类的区别                 接口与抽象类相比,接口的使用几率是最高的,所有的 ...

  7. Linux(kali)基础设置

    本笔记的友情链接 常用目录介绍 boot 存放启动文件 dev 存放设备文件 etc 存放配置文件 home 普通用户家目录,以/home/$username的方式存放 media 移动存储自动挂载目 ...

  8. JVM-学习笔记持续更新

    1.Java虚拟机的基本结构 (1)类加载子系统与方法区: 类加载子系统负责从文件系统或者网络中加载Class信息,加载的类信息存放在一块称为方法区的内存空间.除了类的信息外,方法区中可能还会存放运行 ...

  9. c语言是如何处理函数调用的?

    1.  要编译的测试代码: int plus(int x, int y) { return x + y; } int main(void) { return plus(3, 4); } 2. main ...

  10. 【JavaSE】集合

    Java集合 2019-07-05  12:39:09  by冲冲 1. 集合的由来 通常情况下,程序直到运行时,才知道需要创建多少个对象.但在开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不 ...