[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 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的更多相关文章
- [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 ...
- [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 ...
- 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 ...
- [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 ...
- 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 ...
- 【算法入门】深度优先搜索(DFS)
深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析
转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...
随机推荐
- MVC Model 数据注解与验证
常用验证特性: using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Sch ...
- MD5算法原理
//消息摘要:将任意长度的字符数组处理成定长的字符数组,用于确保原字符串不被修改, //也可以用做密码确认,如果密码一致,则MD5产生后的值必然一致,否则不相同 public class DataUt ...
- linux vi快捷键大全
h或^h 向左移一个字符 j或^j或^n 向下移一行 k或^p 向上移一行 l或空格 向右移一个字符 G 移到文件的最后一行 nG 移到文件的第n行 w 移到下一个字的开头 W 移到下一个字的开头,忽 ...
- OpenSUSE SuSEfirewall2
1,修改SuSEfirewall2配置文件放行相应的端口方法vim /etc/sysconfig/SuSEfirewall2#TCP端口的情况:FW_SERVICES_EXT_TCP ="2 ...
- HDU 5750 Dertouzos
Dertouzos Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- PG数据库之间的导入导出
本文将介绍如何对PG数据库进行导入.导出,主要利用的是PG自带的pg_dump.pg_dumpall.pg_restore.psql等命令,版本是9.4(不同版本的pg_dump \ pg_resto ...
- (3/18)重学Standford_iOS7开发_Objective-C_课程笔记
第三课: 本节课主要是游戏实现的demo,因此我将把课程中简单的几个编程技巧提取出来,重点介绍如何自己实现作业中的要求. 纸牌游戏实现: ①游戏的进行是模型的一部分(理解什么是模型:Model = W ...
- Highcharts可拖动式图表
Highcharts可拖动式图表 默认情况下,Highcharts依据给定的数据列生成图表. 浏览者是无法改动图表的. 假设浏览者须要手动调整数据节点.就须要借助第三方插件Draggable Poin ...
- 将动态库添加到VC程序中
应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息.Visual C++6.0在VC\bin目录下提供了一个名为Dumpbin.ex ...
- [D3 + AngularJS] 15. Create a D3 Chart as an Angular Directive
Integrating D3 with Angular can be very simple. In this lesson, you will learn basic integration as ...