博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
212. Word Search II
阅读量:5763 次
发布时间:2019-06-18

本文共 2809 字,大约阅读时间需要 9 分钟。

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.

Example:

Input: words = ["oath","pea","eat","rain"] and board =[  ['o','a','a','n'],  ['e','t','a','e'],  ['i','h','k','r'],  ['i','f','l','v']]Output: ["eat","oath"]

Note:

You may assume that all inputs are consist of lowercase letters a-z.

 

利用字典树+深度优先遍历的思想。对words中每个word,建立一颗字典树,每个单词的结尾字母上包含这个单词的所有信息。如下图:

那么在字母矩阵中找单词,就可以抽象为,遍历字母矩阵,寻找一条字典树中的路径,这个“路径”的定义,如果某个节点包含单词信息(上图中黄色部分),则认为找到一条路径,即找到一个单词。

1.遍历字母矩阵每个字母,并且从字典树的根节点开始搜索,如果字母是根节点的子树,则继续2。否则next字母。

2.如果字母节点在tree树中有单词信息,则把该单词加入返回的集合中。在矩阵中,访问字母上下左右的四个字母,如果有自己的孩子,则继续搜索下去。每次路径搜索时,都把路径中访问过的节点,设置为visited。

3.遍历结束,会把所有的单词返回。

 

 

 举例:从‘o’开始遍历字母矩阵,发现'o’ 在字典树的根节点的孩子里,寻找路径的步骤移到‘o’节点(该过程是个递归),于是继续遍历其上(无),下(e),左(无),右(a),寻找有没有哪个邻居是在‘o’的孩子里。诶!发现e在自己的孩子节点里;

然后继续从e开始寻找,上(e,但已访问过,pass),下(i),左(无),右(t)。诶!发现t在自己的孩子节点。。。直到h,发现h的节点信息里有单词,诶!加入到res里。这条路径访问就结束了。然后继续从a开始访问,寻找下一条路径。把字符矩阵访问结束后,可得到所有的单词。

 

附代码:

 

#include struct pos {    int x;    int y;     pos(int x,int y):x(x),y(y) {};    pos():x(0),y(0) {};};struct treeNode{    string str;    treeNode* child[26];    treeNode()    {        str = "";        for(int i = 0;i<26;i++)            child[i] = NULL;    }};struct WordTree{    treeNode* root;    WordTree()    {        root = new treeNode();    }        //这样构建字典树    //保证相同的单词,只出现一次    void insert(string s)    {        int len = s.length();        if(len<=0) return;        treeNode* p=root;        for(int i=0;i
child[index]) { p->child[index] = new treeNode(); } p = p->child[index]; } p->str = s; }};void search(vector
>& board,treeNode* p, int i,int j,vector
& res,vector
>& visited){ if(!p->str.empty()) { res.push_back(p->str); p->str.clear(); } visited[i][j] = true; int direction[][2] = { {-1,0},{ 1,0},{ 0,-1},{ 0,1}}; for (int k = 0; k < 4; k++) { int nx = i + direction[k][0]; int ny = j + direction[k][1]; //先判断坐标的有效性 if(nx>=0 && nx
=0 && ny
child[board[nx][ny]-'a']&&!visited[nx][ny]) { search(board,p->child[board[nx][ny]-'a'],nx,ny,res,visited); } } } } visited[i][j] = false;}class Solution {public: vector
findWords(vector
>& board, vector
& words) { vector
res; if (words.empty() || board.empty() || board[0].empty()){ return res; } WordTree tree; vector
> visited(board.size(), vector
(board[0].size(), false)); //构建字典树 for (int i=0; i
child[board[i][j] - 'a']) { search(board, tree.root->child[board[i][j] - 'a'], i, j, res,visited); } } } return res; }};

 

 

 

 

转载于:https://www.cnblogs.com/LUO77/p/10553971.html

你可能感兴趣的文章
JS中比较数字大小
查看>>
springcloud 学习-eureka搭建-为eureka添加认证
查看>>
jQuery插件的开发
查看>>
基础,基础,还是基础之JAVA基础
查看>>
如何成为一个C++高级程序员
查看>>
ant android 打包签名和渠道
查看>>
我的友情链接
查看>>
显式锁(第十三章)
查看>>
看linux书籍做的一些重要笔记(2011.07.03更新)
查看>>
CString、Char* ,char [20]、wchar_t、unsigned short转化
查看>>
从案例学RxAndroid开发(上)
查看>>
Redis学习手册(内存优化)
查看>>
浅尝TensorFlow on Kubernetes
查看>>
springboot系列十 Spring-Data-Redis
查看>>
excel进行矩阵计算
查看>>
基于Android平台的动态生成控件和动态改变控件位置的方法
查看>>
linux 死机分析
查看>>
BOM
查看>>
iOS: Block的循环引用
查看>>
mysql实战02 | 日志系统:一条SQL更新语句是如何执行的?
查看>>