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.

头次接触这类题目,对我来说还是有难度的,其实这类题的难点就在于,单纯的DFS,是无法在回溯到某一点的时候去改变该点的状态,因为你无法判断回溯到了哪一点(至少我没有做出来~)。那么用一个for循环,里面是递归这种形式,可以做到的,我想这就是回溯和所谓的DFS的区别吧。

我做过的与该题类似的题目:

Letter Combinations of a Phone Number(带for循环的DFS,组合问题,递归总结)

leedcode:Combinations

  算法核心:回溯在现实生活中就是一种试探的尝试,例如,你很久以前去过一个地方,只很清楚记得目的地的一个特征(假设到时你能知道),现在你在一个十字路口,不知哪个方向是目的地所在的方向,那就只能选择一个方向进行试探,如果运气不好的话,错了,就只能回到十字路口,在进行下一个方向的尝试,这个回到十字路口就是一种回溯

  回到该题思路:首先找到头节点,然后开始深搜,深搜的过程需要记录该点是否被纳入到我们的路径中,因为每个点是只能用一次的。

  错误DFS代码,因为他在回溯的时候无法改变已经访问过的点,如果我们在某一点a[i][j]处,它的上下都能走,但是上只能走一步(也就是说a[i-1][j]的上下左右都是不符合条件的),所以我们在回到a[i][j]处的时候需要把刚刚向上走的那一点(a[i-1][j])的访问状态置回false,因为该点可能在以后成为我们需要再次访问的点,但是现在我们并没有把该点加入到我们的路径中:

class Solution {
private:
vector<vector<char>> m_board;
bool visited[][];
string m_word;
int max_row;
int max_col;
public:
bool dfs(int dep,int i,int j)
{
if(i<||i==max_row||j<||j==max_col)
return false;
if(m_board[i][j]!=m_word[dep])
return false;
if(dep!=m_word.size()-)
visited[i][j]=true;
if(visited[i][j]==false&&dep==m_word.size()-)
return true; return dfs(dep+,i-,j)||dfs(dep+,i+,j)||dfs(dep+,i,j-)||dfs(dep+,i,j+);//某一层的上下左右都无路的时候,要把访问标志置回false
}
bool exist(vector<vector<char>> &board, string word) {
//找到起始位置
m_board=board;
m_word=word;
max_row=m_board.size();
max_col=m_board[].size();
for (int i=;i<max_row;++i)
{
for (int j=;j<max_col;++j)
{
if(m_board[i][j]==m_word[]){
memset(tag,,sizeof(tag));
visited[i][j]=true;
if(dfs(,i,j))
return true;
else {  
        continue;
        visited[i][j]=false;
        }
}
}
}
return false;
}
};

简单说下我的理解:以前一个点为基础,来搜索它的上下左右,若搜到一点,则一直往下,直到”撞墙“或者不满足条件,就回溯。就是这种走到顶,然后回溯,又走又回溯,直到找到最后的结果。

参考代码:

const int MAX=;
int dire[][]={-,,,,,-,,};
bool visited[MAX][MAX];
class Solution {
private:
vector<vector<char>> m_board;
string m_word;
int max_row;
int max_col;
bool res;
public:
void dfs(int dep,int i,int j)
{
if(dep==m_word.size()){
res=true;
return;
}
for (int q=;q<;++q)
{
int newi=dire[q][]+i;
int newj=dire[q][]+j;
if(newi>=&&newi<max_row&&newj>=&&newj<max_col&&m_board[newi][newj]==m_word[dep]&&!visited[newi][newj])
{
visited[newi][newj]=true;
dfs(dep+,newi,newj);
visited[newi][newj]=false;//该位置上下左右都不通
}
}
}
bool exist(vector<vector<char>> &board, string word) {
//找到起始位置
res=false;
m_board=board;
m_word=word;
max_row=m_board.size();
max_col=m_board[].size();
for (int i=;i<max_row;++i)
{
for (int j=;j<max_col;++j)
{
if(m_board[i][j]==m_word[]){
memset(visited,,sizeof(visited));
visited[i][j]=true;
dfs(,i,j);
if(res)
return true;
else{
visited[i][j]=false;
continue;
}
}
}
}
return false;
}
}; int main()
{
freopen("C:\\Users\\Administrator\\Desktop\\a.txt","r",stdin);
vector<char> a;a.push_back('A');a.push_back('B');a.push_back('C');a.push_back('F');
vector<char> b;b.push_back('W');b.push_back('G');b.push_back('C');b.push_back('G');
vector<char> c;c.push_back('B');c.push_back('A');c.push_back('F');c.push_back('Q');
vector<vector<char>> d;
d.push_back(a);d.push_back(b);d.push_back(c);
Solution so;
cout<<so.exist(d,"ABCCF")<<endl;
cout<<so.exist(d,"FGQ")<<endl;
cout<<so.exist(d,"ABCCGQFAG")<<endl;
return ;
}

Word Search(深度搜索DFS,参考)的更多相关文章

  1. [LeetCode OJ] Word Search 深度优先搜索DFS

    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] Word Search 词语搜索

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

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

  5. 079 Word Search 单词搜索

    给定一个二维面板和一个单词,找出该单词是否存在于网格中.这个词可由顺序相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格.同一个单元格内的字母不允许被重复使用.例如,给定 二 ...

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

  7. Leetcode79. Word Search单词搜索

    给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格.同一个单元格内的字 ...

  8. 数据结构之 栈与队列--- 走迷宫(深度搜索dfs)

    走迷宫 Time Limit: 1000MS Memory limit: 65536K 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方 ...

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

随机推荐

  1. poj3662 Telephone Lines

    思路: 二分+最短路.最短路也可以用来计算从a到达b所需的边权不超过x的边的数量. 实现: #include <cstdio> #include <cmath> #includ ...

  2. T4870 水灾(sliker.cpp/c/pas) 1000MS 64MB

    题目描述 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY所在的城市可以用一个N*M(N,M<=50)的地图表 ...

  3. Farseer.net轻量级ORM开源框架 V1.0 开发目标

    本篇主要给大家说明下在V1.0中,计划开发的任务的状态.按照国际惯例.上大表格 开发计划状态 编号 模块 状态 说明 1  分离Utils.Extend.UI  √  在V0.2版本中,是集成在一个项 ...

  4. 富文本KindEditor使用

    1.官网down KindEditor,添加到自己的项目中:添加时可把不需要的文件夹干掉,asp/php等等.我的项目用的是纯html和js,直接调用后台api: 2.页面引入相关js.eclipse ...

  5. 关于NSCELL

    作为一个初学者,我一直很弄不明白NSCell的子类,比如,NSButtonCell,NSImageCell及其对应的控件之间的关系.今天,在做一个TableView实现的时候,我终于开始有点悟了——好 ...

  6. hibernate 离线查询(DetachedCriteria)

    离线查询使用DetachedCriteria对象设置限制条件,然后再通过session获取Criteria对象. 使用场景: 例如Biz类和Dao类,在Dao类中利用session操作CRUD,如果你 ...

  7. nginx配置实现负载均衡

    一.负载均衡的作用 1.转发功能 按照一定的算法[权重.轮询],将客户端请求转发到不同应用服务器上,减轻单个服务器压力,提高系统并发量. 2.故障移除 通过心跳检测的方式,判断应用服务器当前是否可以正 ...

  8. js判断图片是否有效

    var ImgObj=new Image(); ImgObj.src= 'http://192.168.10.6:8082/3D/SERVER_1_DELL_880.jpg'; if(ImgObj.f ...

  9. 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)

    议题:基于堆的优先级队列(最大堆实现) 分析: 堆有序(Heap-Ordered):每个节点的键值大于等于该节点的所有孩子节点中的键值(如果有的话),而堆数据结构的所有节点都按照完全有序二叉树 排.当 ...

  10. [LUOGU] P2251 质量检测

    题目背景 无 题目描述 为了检测生产流水线上总共N件产品的质量,我们首先给每一件产品打一个分数A表示其品质,然后统计前M件产品中质量最差的产品的分值Q[m] = min{A1, A2, ... Am} ...