Given a 2D board and a word, find if the word exists in the grid.

The word can 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.

For example,
Given board =

[
["ABCE"],
["SFCS"],
["ADEE"]
]

word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.

典型的搜索问题,这道题目用了两种方法来做。

一种用到动态规划的思想,用一个vector记录下word中前i个字符构成的子串的所有搜索路径,然后对于前i+1个字符构成的子串

查找搜索路径时,只需判断第i+1个字符在当前由前i个字符构成的子串的搜索路径的最后一个位置的上下左右四个方向是否出现,

如果出现则保存新的路径。最后只需判断查找word时是否有可行的搜索路径存在,如果有,则返回true,否则,返回false。但是,

这种方法的复杂度很高,对于大的测试数据,出现TLE。

 class Solution {
public:
bool exist(vector<vector<char> > &board, string word) {
map<int, vector<vector<unsigned> > > path; //path[i]表示word中的前i个字符构成的字符串在board中的查找路径,一共有path[i].size()条合法查找路径
if(word.size()==)
return true;
int width = board[].size();
for(unsigned i=; i<board.size()*width; i++)
{
if(board[i/width][i%width]==word[])
{
vector<unsigned> start;
start.push_back(i);
path[].push_back(start);
}
}
for(unsigned i=; i<word.size(); i++)
{
char c = word[i];
//vector<vector<unsigned> > pt = path[i-1]; for(vector<vector<unsigned> >::iterator it=path[i].begin(); it!=path[i].end(); it++)
{
vector<unsigned> unipath = *it; int lastpos = unipath.back(); if((lastpos-width)>= && board[(lastpos-width)/width][(lastpos-width)%width]==c && find(unipath.begin(), unipath.end(), (lastpos-width))==unipath.end())
{
unipath.push_back(lastpos-width);
path[i+].push_back(unipath);
unipath.pop_back();
}
if((lastpos+width)<(board.size()*width) && board[(lastpos+width)/width][(lastpos+width)%width]==c && find(unipath.begin(), unipath.end(), (lastpos+width))==unipath.end())
{
unipath.push_back(lastpos+width);
path[i+].push_back(unipath);
unipath.pop_back();
}
if(lastpos%width> && board[(lastpos-)/width][(lastpos-)%width]==c && find(unipath.begin(), unipath.end(), (lastpos-))==unipath.end())
{
unipath.push_back(lastpos-);
path[i+].push_back(unipath);
unipath.pop_back();
}
if((lastpos%width)<(width-) && board[(lastpos+)/width][(lastpos+)%width]==c && find(unipath.begin(), unipath.end(), (lastpos+))==unipath.end())
{
unipath.push_back(lastpos+);
path[i+].push_back(unipath);
unipath.pop_back();
}
if(i==word.size()- && path[word.size()].size()!=)
return true;
}
}
if(path[word.size()].size()==)
return false;
else
return true;
}
};

第二种是用到DFS(深度优先搜索),先找到可行的起始点,然后对于每个起始点判断是否有一条合法搜索路径存在,如果找到

一条合法搜索路径,则不进行后续搜索,直接返回true。如果所有可能的路径验证都不成立后,最后返回false。测试AC。

 void search(vector<vector<char> > &board, string word, vector<int> &path, bool &flag)
{
if(word.size()==)
{
flag = true;
return;
} int width = board[].size();
char c = word[];
if(path.size()==)
{
for(unsigned i=; i<board.size()*width; i++)
{
if(board[i/width][i%width]==c)
{
path.push_back(i);
search(board, word.substr(), path, flag);
if(flag==true)
return;
path.pop_back();
}
}
}
else
{
int lastpos = path.back();
if((lastpos-width)>= && board[(lastpos-width)/width][(lastpos-width)%width]==c && find(path.begin(), path.end(), (lastpos-width))==path.end())
{
path.push_back(lastpos-width);
search(board, word.substr(), path, flag);
if(flag==true)
return;
path.pop_back();
}
if((lastpos+width)<(board.size()*width) && board[(lastpos+width)/width][(lastpos+width)%width]==c && find(path.begin(), path.end(), (lastpos+width))==path.end())
{
path.push_back(lastpos+width);
search(board, word.substr(), path, flag);
if(flag==true)
return;
path.pop_back();
}
if(lastpos%width> && board[(lastpos-)/width][(lastpos-)%width]==c && find(path.begin(), path.end(), (lastpos-))==path.end())
{
path.push_back(lastpos-);
search(board, word.substr(), path, flag);
if(flag==true)
return;
path.pop_back();
}
if((lastpos%width)<(width-) && board[(lastpos+)/width][(lastpos+)%width]==c && find(path.begin(), path.end(), (lastpos+))==path.end())
{
path.push_back(lastpos+);
search(board, word.substr(), path, flag);
if(flag==true)
return;
path.pop_back();
} } } class Solution {
public:
bool exist(vector<vector<char> > &board, string word) {
bool flag = false;
vector<int> path; search(board, word, path, flag); return flag;
}
};

[LeetCode OJ] Word Search 深度优先搜索DFS的更多相关文章

  1. [LeetCode] 79. Word Search 单词搜索

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

  2. [LeetCode] 79. Word Search 词语搜索

    Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...

  3. LeetCode 79. Word Search单词搜索 (C++)

    题目: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed fr ...

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

  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. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...

  7. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  8. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  9. 深度优先搜索DFS和广度优先搜索BFS简单解析

    转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...

随机推荐

  1. Java中Map遍历的四种方案

    在Java中如何遍历Map对象 方式一 这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer, Integer> map = new HashM ...

  2. HW4.28

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  3. Tornado自定义分布式session框架

    一.session框架处理请求执行的流程: 1.服务器端生成随机的cookie字符串 2.浏览器发送请求,服务器将cookie返回给浏览器. 3.服务器在生成一个字典.字典的key为cookie,va ...

  4. Python运行机制

    闲来无事,简单画了一下Python的运行机制,纯属娱乐:

  5. MySQL 优化Limit分页

    很多时候.我们需要选择出从指定位置开始的指定行数.此时.limit笑了     对于limit的定义是:     limit x,y     表示从第x行开始选择y条记录          在业务需要 ...

  6. JAVA基础英语单词表(上)

    action                            / 'ækʃən /          动作,行为 active                           / 'ækti ...

  7. engine的工具中实现Snapping(捕捉)

    在Engine的工具(ITool)里: OnClick事件处理函数中: 首先需要获取一个图层,作为Snapping的参照, IFeatureLayer targetLayer 然后声明一个IMoveP ...

  8. 8086FLAG寄存器

    8086中的FLAG寄存器也就是状态标志位寄存器.它用来存储一些指令的计算结果,比如加法减法中的进位:为CPU运行某些命令提供根据,比如DF它决定是往前走指针还是向后走指针:总之状态寄存器存放的被称为 ...

  9. TCP keepalive under Linux

    TCP Keepalive HOWTO Prev   Next 3. Using TCP keepalive under Linux Linux has built-in support for ke ...

  10. 【原】window上安装elasticserach

    [window上安装elasticserach] 系统环境:2008R2 x64测试安装用的服务器IP:192.168.12.52elasticsearch版本:2.3.4JDK版本:jdk 1.8. ...