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. MRC BlOCK ARC

       /*-------------------MRC环境中-------------------------*/     //使用局部变量:a到block块中,为了在block中能够使用这个变量,将 ...

  2. iOS-tableView点击下拉菜单

    #import "ViewController.h" @interface ViewController ()<UITableViewDataSource,UITableVi ...

  3. C++服务器设计(七):聊天系统服务端实现

    在之前的章节中,我们对服务端系统的设计实现原理进行了剖析,在这一章中,我们将对服务端框架进行实际运用,实现一款运行于内网环境的聊天系统.该聊天系统由客户端与服务器两部分组成,同时服务端通过数据库维护用 ...

  4. Mr. Kitayuta's Colorful Graph 多维并查集

    Mr. Kitayuta's Colorful Graph 并查集不仅可以用于一维,也可以用于高维. 此题的大意是10W个点10W条边(有多种颜色),10W个询问:任意两个节点之间可以由几条相同颜色的 ...

  5. Sigmoid function in NN

    X = [ones(m, ) X]; temp = X * Theta1'; t = size(temp, ); temp = [ones(t, ) temp]; h = temp * Theta2' ...

  6. CSS样式中,background-image 背景图片居中显示并且在不同屏幕分辨率下始终居中

    body {   margin-top:0px; margin-right:0px;   margin-bottom:0px;   margin-left:0px;   background-colo ...

  7. Python学习笔记五,函数及其参数

    在Python中如何自定义函数:其格式为 def 函数名(函数参数): 内容

  8. linux----ulimit 限制

    ulimit -a 显示当前用户的各种限制. ulimit -n 的数值表示每个进程可以打开的文件数目. 一般情况下, ulimit -n 的数值是1024. 当进程打开的文件数目超过此限制时,该进程 ...

  9. 超大文件上传到Azure Linux虚拟机最佳实践

    客户在实际进行迁移的时候,往往碰到需要将本地数据中心的超大文件,比如单个200GB的文件,或者总共1TB的无数文件上传到Azure上的情况,尤其是传到Azure的Linux虚拟机的场景,这种场景包括: ...

  10. 【转】iOS代码规范

    原文地址: http://www.cocoachina.com/ios/20150908/13335.html 简介: 本 文整理自Apple文档<Coding Guidelines for C ...