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. Web---session技术代码演示(request,session,servletContext)

    Session会话简介与基本知识点 当浏览器第一次访问服务器时,无论先访问哪一个页面,服务器就会给用户分配一个唯一的会话标识,即jsessionid然后以cookie的形式返回给用户. 会话是指在一段 ...

  2. java NIO 资料总结

    1.http://developer.51cto.com/art/201204/328340.htm 2.http://ifeve.com/file-channel/并发编程网系列 3 http:// ...

  3. 使用二维NDRange workgroup

    作为初学者一直,经过多次的上网搜索你一定会看到迈克老狼的向量加法的示例,不知道你是否和我一样,刚开始并不是很准确的知道他的add.cl写的代码的意思,源码如下: #pragma OPENCL EXTE ...

  4. Spark RDD/Core 编程 API入门系列之map、filter、textFile、cache、对Job输出结果进行升和降序、union、groupByKey、join、reduce、lookup(一)

    1.以本地模式实战map和filter 2.以集群模式实战textFile和cache 3.对Job输出结果进行升和降序 4.union 5.groupByKey 6.join 7.reduce 8. ...

  5. wDatePicker使用说明文档

    版权声明:本文为博主原创文章,未经博主允许不得转载. http://www.my97.net/dp/demo/ 4.5更新的内容 [重构]对WdatePicker.js做了较大规模的调整 [改进]自动 ...

  6. Linux防火墙iptables学习笔记(三)iptables命令详解和举例[转载]

     Linux防火墙iptables学习笔记(三)iptables命令详解和举例 2008-10-16 23:45:46 转载 网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能 ...

  7. Foundation与coreFoundation的相互转换

    今天在整理以前的一些琐碎知识,今天就分享一个Foundation与coreFoundation的相互转换细节问题,其中的引用计数器是需要考虑的方面.   ARC 环境下,CoreFoundation框 ...

  8. 使用 CAS 在 Tomcat 中实现单点登录

    单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.CAS ...

  9. 自主创建tcpdump/wireshark pcap文件

      pcap文件格式是bpf保存原始数据包的格式,很多软件都在使用,比如tcpdump.wireshark等等,了解pcap格式可以加深对原始数据包的了解,自己也可以手工构造任意的数据包进行测试. p ...

  10. python学习笔记--Django入门四 管理站点--二

    接上一节  python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...