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. Linux中oracle安装时候报ora-00119解决办法

    ORA-00119: invalid specification for system parameter LOCAL_LISTENER ORA-00130: invalid listener add ...

  2. iOS-设计模式之通知

    通知设计模式简单好用,就是一个项目中如果用的太多,不利于代码维护,可读性太差. 实现过程: [[NSNotificationCenter defaultCenter]postNotificationN ...

  3. 编写简单的 NT 式驱动程序的加载与卸载工具

    写驱动的加载需要用到五个函数: OpenSCManager() CreateService() OpenService() StartService() CloseServiceHandle() 这五 ...

  4. css:hover选择器

    :hover 选择器用于选择鼠标指针浮动上面的元素. :hover选择器可以用于所有的元素,不单是链接. 提示::link选择器设置指向未被访问页面的链接的样式,:visited选择器用于设置指向已被 ...

  5. java poi 合并单元格后边框问题

    在项目中用poi合并单元格,但发现边框会有不显示的问题. 在网上搜集了答案,来记录一下. 解决方法: 将每个没用到的单元格都设空值. 例如: HSSFCell cell = row.createCel ...

  6. css white-space

    以下是对上面几个属性的测试效果如下: 具体代码如下: <!DOCTYPE html> <html lang="en"> <head> <m ...

  7. XML为数据库进行增删改查(实例)

    //增删改查文件 package xml2; import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.Fi ...

  8. 50个必备的实用jQuery代码段+ 可以直接拿来用的15个jQuery代码片段

    50个必备的实用jQuery代码段+ 可以直接拿来用的15个jQuery代码片段 本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从j ...

  9. 高可用集群(HA)之Keeplived原理+配置过程

    原理--> 通过vrrp协议,定义虚拟路由,在多个服务节点上进行转移. 通过节点优先级,将初始虚拟路由到优先级高的节点上,checker工作进程检测到主节点出问题时,则降低此节点优先级,从而实现 ...

  10. showModalDialog(转)

    基本介绍:          showModalDialog()         (IE 4+ 支持)          showModelessDialog()      (IE 5+ 支持)    ...