题目

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.

分析

开始采用回溯递归的方法实现,但是LeetCode的测试平台给出一个找不到Search的编译error,很是奇怪,待找到问题,再来更新。

CE代码

class Solution {
public: bool Search(vector<vector<char> > &board, int &x, int &y, string &word, vector<vector<int> > &isVisited)
{
if (word.empty())
return true; //当前字符有4个查找方向上、下、左、右
vector<vector<int> > Direction = { { 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 } };
for (size_t i = 0; i < Direction.size(); ++i)
{
//要查找的下一个字符
int xx = x + Direction[i][0];
int yy = y + Direction[i][1];
if (xx >= 0 && yy >= 0 && xx < board.size() && yy < board[xx].size() && isVisited[xx][yy] == 0 && board[xx][yy] == word[0])
{
isVisited[xx][yy] = 1;
if (word.length() == 1 || Search(board, xx, yy, word.substr(1), isVisited))
return true;
isVisited[xx][yy] = 0;
}//if
}//for
return false;
} bool exist(vector<vector<char>>& board, string word) {
if (board.empty() || board[0].empty())
return false; if (word.empty())
return true; int m = board.size();
int n = board[0].size(); vector<vector<int> > isVisited(m, vector<int>(n, 0)); for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (!word.empty() && board[i][j] == word[0])
{
//修改访问标志为1 代表已访问
isVisited[i][j] = 1;
if (word.length() == 1 || Search(board, i, j, word.substr(1), isVisited))
return true;
//若没有找到目标串,则从下一个字符重新查找,将当前字符访问标志改为0
isVisited[i][j] = 0;
}
}//for
}//for
return false;
}
};

AC代码

此处代码源于参考博客,收益良多,谢谢博主。

其思想是:

用栈记录当前搜索的路径。

栈存放的节点包括4个成员: 字符c, x,y坐标,已遍历方向p。

注意p在回溯法中是非常重要的,用来记录已遍历过的方向(按照上下左右的顺序),不然的话就会出现无限循环的同一节点进栈出栈。

进栈之后的节点置为’*’,以免同一节点多次进栈。

出栈之后的节点恢复为word[wind]。

struct Node
{
char c;
int x;
int y;
int p; //next trial is 0-up, 1-down, 2-left, 3-right
Node(char newc, int newx, int newy, int newp): c(newc), x(newx), y(newy), p(newp) {}
}; class Solution {
public:
bool exist(vector<vector<char> > &board, string word) {
if(board.empty() || board[0].empty())
return false;
int m = board.size();
int n = board[0].size(); for(int i = 0; i < m; i ++)
{
for(int j = 0; j < n; j ++)
{
if(board[i][j] == word[0])
{// maybe a success
stack<Node> stk;
Node curnode(word[0], i, j, 0);
stk.push(curnode);
board[curnode.x][curnode.y] = '*';
int wind = 1;
if(wind == word.size())
return true;
while(!stk.empty())
{
if(stk.top().p == 0)
{
stk.top().p = 1;
if(stk.top().x > 0 && board[stk.top().x-1][stk.top().y] == word[wind])
{
Node nextnode(word[wind], stk.top().x-1, stk.top().y, 0);
stk.push(nextnode);
board[nextnode.x][nextnode.y] = '*';
wind ++;
if(wind == word.size())
return true;
continue;
}
}
if(stk.top().p == 1)
{
stk.top().p = 2;
if(stk.top().x < m-1 && board[stk.top().x+1][stk.top().y] == word[wind])
{
Node nextnode(word[wind], stk.top().x+1, stk.top().y, 0);
stk.push(nextnode);
board[nextnode.x][nextnode.y] = '*';
wind ++;
if(wind == word.size())
return true;
continue;
}
}
if(stk.top().p == 2)
{
stk.top().p = 3;
if(stk.top().y > 0 && board[stk.top().x][stk.top().y-1] == word[wind])
{
Node nextnode(word[wind], stk.top().x, stk.top().y-1, 0);
stk.push(nextnode);
board[nextnode.x][nextnode.y] = '*';
wind ++;
if(wind == word.size())
return true;
continue;
}
}
if(stk.top().p == 3)
{
stk.top().p = 4;
if(stk.top().y < n-1 && board[stk.top().x][stk.top().y+1] == word[wind])
{
Node nextnode(word[wind], stk.top().x, stk.top().y+1, 0);
stk.push(nextnode);
board[nextnode.x][nextnode.y] = '*';
wind ++;
if(wind == word.size())
return true;
continue;
}
}
//restore
board[stk.top().x][stk.top().y] = stk.top().c;
stk.pop();
wind --;
}
}
}
}
return false;
}
};

GitHub测试程序源码

LeetCode(79) Word Search的更多相关文章

  1. LeetCode(79): 单词搜索

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

  2. LeetCode(173) Binary Search Tree Iterator

    题目 Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ...

  3. LeetCode(290) Word Pattern

    题目 Given a pattern and a string str, find if str follows the same pattern. Here follow means a full ...

  4. Leetcode(8)字符串转换整数

    Leetcode(8)字符串转换整数 [题目表述]: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我 ...

  5. LeetCode(275)H-Index II

    题目 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimi ...

  6. LeetCode(220) Contains Duplicate III

    题目 Given an array of integers, find out whether there are two distinct indices i and j in the array ...

  7. LeetCode(154) Find Minimum in Rotated Sorted Array II

    题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...

  8. LeetCode(122) Best Time to Buy and Sell Stock II

    题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...

  9. LeetCode(116) Populating Next Right Pointers in Each Node

    题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...

随机推荐

  1. 《统计学习方法》笔记九 EM算法及其推广

    本系列笔记内容参考来源为李航<统计学习方法> EM算法是一种迭代算法,用于含有隐变量的概率模型参数的极大似然估计或极大后验概率估计.迭代由 (1)E步:求期望 (2)M步:求极大 组成,称 ...

  2. 转 open_cursors参数设置调优

    https://www.cnblogs.com/Peyton-for-2012/archive/2013/05/07/3065058.html

  3. python学习之TCP/UDP

    TCP/UDP都是网络编程(socket)的两种基于C/S结构的程序. UDP的9999端口与TCP的9999端口可以各自绑定. UDP:非可靠连接速度快,服务器:创建socket 绑定ip和端口后直 ...

  4. python学习之内部函数:

    python内置函数表:https://docs.python.org/3/library/functions.html 1 判断数据类型的函数:isinstance(变量, 待要判断的类型) 2判断 ...

  5. [译]Understanding ECMAScript6 迭代器与生成器(未完)

    迭代器在许多编程语言中被作为一种更易处理数据集合的方式被使用.在ECMAScript6中,JavaScript添加了迭代器,将其作为此语言的一个重要特征.当再加上新的方法和新的集合类型(比如集合与映射 ...

  6. HDU Atlantis 线段树 表达区间 矩形面积相交

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 我的做法是把x轴的表示为线段,然后更新y 不考虑什么优化的话,开始的时候,把他们表达成线段,并按y排序,然 ...

  7. Nginx 配置https 开启ssl 同时支持http

    server { listen ; listen 443 ssl; server_name default; index index.html index.php; root /www/html; a ...

  8. Android studio 断点调试

          最近进行业务测试,总是被测试环境不稳定或者测试数据错误困扰,一有问题就去找开发,自己都觉得很烦,所以就自己学着调试起来,这样以后遇到问题就可以自己定位的更深入了.   1.确保连接设备且进 ...

  9. GetClassName 取得的类名有

    今天上午稍微跟踪了一下自己的项目里面的各个空间,得知GetClassName可以取到以下类名:Static\Edit\Button\ComboBox\msctls_trackbar32\SysTabC ...

  10. AndroidStudio第一次提交项目代码到git服务器/github

    虽然使用AndroidStudio(以下简称as)开发并使用git管理代码已经有很长时间,但是第一次提交项目到git依然会很不顺利,网上的文章或许因为所使用版本比较老,并不一定完全凑效,因此写此笔记做 ...