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

一.思路类比

在Word Search:http://www.cnblogs.com/zengzy/p/4941110.html中说过,一个单词word在board中搜索的时间复杂度为O(m*n*m*n),如果有k个word那么时间复杂度是o(k*m*n*m*n)。那么,是否好优化一点的方式呢?我们对比Word Search2和1的不同,会发现,WS2(Word Search2)就是有k个单词,而WS1只有一个单词,所以我们希望有一种结构可以把k个单词组织起来,使得我们在k个单词中查找某个单词就像在只在一个单词中查找一样,换句话说就是,我们希望在k个单词中查找某个单词的时间成本是O(word_length)。这种结构可以借用树+哈希来完成,单词的每个字母就是树中的一个结点,而下一个字母就是该结点的下一个结点,可以用哈希表存储,而这种结构也叫字典树或键树。

二.时间复杂度

上文已经描述过,虽然有k个单词,但其对外表现就像只有一个单词,因此时间复杂度还是O(m*n*m*n)。

三.空间复杂度

在该题中,结点的子结点可以使用一个大小为26的数组表示,即26叉树:

struct node{

char c;//结点值

bool isWord;该结点是否为某个单词的结尾

struct node* children[26];

}

树的高度为最长单词的长度,设为len,那么空间复杂度为o(26^0+26^2+...+26^len)

四.代码,注意此处代码中存在内存泄露的问题,因为new之后析构函数并没有释放掉内存。

class Tree;
class Solution;
class Node{
public:
friend class Tree;
friend class Solution;
private:
char _c;
bool _isword;
vector<Node*> _children;
public:
Node(char c,bool isword=false,size_t children_size=):_c(c),_isword(isword),_children(children_size,NULL){}
bool getIsWord()
{
return _isword;
}
}; class Tree{
private:
Node* _root;
public:
Tree(Node* root=NULL)
{
_root = root ;
}
void insert(const string& insert_str)
{
size_t insert_str_size = insert_str.size();
Node* cur = _root;
for(size_t i=;i<insert_str_size;i++){
if(cur->_children[insert_str[i]-'a']==NULL){
Node *node = new Node(insert_str[i],false,);
cur->_children[insert_str[i]-'a']=node;
cur = node;
}else{
cur = cur->_children[insert_str[i]-'a'];
}
}
cur->_isword = true;
}
Node* getRoot()
{
return _root;
}
}; class Solution {
public:
void dfs(vector<vector<char>>& board,vector<vector<bool>>& visited,unordered_set<string>& sets,string& str,Node* node,int row,int col,int cur_r,int cur_c)
{
if(cur_r< || cur_r>=row || cur_c< || cur_c>=col || visited[cur_r][cur_c]){
return ;
}
visited[cur_r][cur_c] = true;
char c = board[cur_r][cur_c] ;
str.push_back(c);
Node* child = node->_children[c-'a'];
if(child != NULL){
if(child->getIsWord())
sets.insert(str);
dfs(board,visited,sets,str,child,row,col,cur_r-,cur_c);
dfs(board,visited,sets,str,child,row,col,cur_r,cur_c+);
dfs(board,visited,sets,str,child,row,col,cur_r+,cur_c);
dfs(board,visited,sets,str,child,row,col,cur_r,cur_c-);
}
visited[cur_r][cur_c] = false;
str.pop_back();
} vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
vector<string> res;
if(board.empty()){
return res;
}
Tree root(new Node('#',false,));
for(size_t i=;i<words.size();i++){
root.insert(words[i]);
}
int row = board.size();
int col = board[].size();
vector<vector<bool>> visited(row,vector<bool>(col,false));
string str;
unordered_set<string> sets;
for(size_t i=;i<row;i++){
for(size_t j=;j<col;j++){
dfs(board,visited,sets,str,root.getRoot(),row,col,i,j);
}
}
for(auto iter = sets.begin();iter!=sets.end();iter++){
res.push_back(*iter);
}
return res;
}
};

Word Search II的更多相关文章

  1. Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)

    Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...

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

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

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

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

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

  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 词语搜索之二

    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() Word Search II

    超时,用了tire也不行,需要再改. class Solution { class TrieNode { public: // Initialize your data structure here. ...

随机推荐

  1. Entity Framework Code First主外键关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  2. 单机/伪分布式Hadoop2.4.1安装文档

    转载自官方文档,最新版请见:http://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-common/SingleCluster.h ...

  3. Maven 学习笔记

    1. Maven 工具的意义: 从事软件开发,无论什么样的项目,什么样的技术,都要经历:编码.测试.打包.发布等几个特定过程,而这些过程在软件开发周期中都是重复的.繁琐的.Maven的出现是为了将开发 ...

  4. zepto.1.1.6.js源码中的each方法学习笔记

    each方法接受要遍历的对象和对应的回调函数作为参数,它的作用是: 1.如果要遍历的对象是类似数组的形式(以该对象的length属性值的类型是否为number类型来判断),那么就把以要遍历的对象为执行 ...

  5. mac 更改word的默认显示比例为125

    1.打开或新建一个word文档 2.按 fn + option + F11 键,会弹出一个[项目]窗口,选中Normal, 双击[模块], 修改为125 Sub AutoOpen() ActiveWi ...

  6. 用Python写的简单脚本更新本地hosts

    这两天Google墙得严重,于是就产生了做个一键更新hosts的脚本的想法. 由于正在学习Python,理所当然用Python来写这个脚本了. 接触比较多的就是urllib2这个库,习惯性的impor ...

  7. C# Directory类

    Directory类 是一个静态类,常用的地方为创建目录和目录管理. 一下来看看它提供的操作. 1.CreateDirectory 根据指定路径创建目录.有重载,允许一次过创建多个目录. 2.Dele ...

  8. 使用 asp.net Web API 2的坑

    使用工具: Googl  浏览器+PostMan 插件 写了个  控制器 添加了个Action,结果呢?GET 方式请求没问题. POST一直,在服务器端获取不了参数...找了官方的文档 .各种雨里雾 ...

  9. Cocos2d-x 2.1.5 简单动画

    Cocos2d新版本函数更改了一些. 下面的代码可以产生一个简单动画. //第一步:生成动画需要的数据 CCTexture2D *texture=CCTextureCache::sharedTextu ...

  10. 使用 ServKit(PHPnow) 搭建 PHP 环境[图]

    http://servkit.org/guide 搭建 PHP 其实不很难,只是有点繁琐.要是自己搭建一次 PHP + MySQL 环境很是费时.更糟的是,很多新手在配置 PHP 时常常出现这样那样的 ...