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 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;
}
};
LeetCode(79) Word Search的更多相关文章
- LeetCode(79): 单词搜索
Medium! 题目描述: 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格.同一个单元 ...
- LeetCode(173) Binary Search Tree Iterator
题目 Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ...
- LeetCode(290) Word Pattern
题目 Given a pattern and a string str, find if str follows the same pattern. Here follow means a full ...
- Leetcode(8)字符串转换整数
Leetcode(8)字符串转换整数 [题目表述]: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我 ...
- LeetCode(275)H-Index II
题目 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimi ...
- LeetCode(220) Contains Duplicate III
题目 Given an array of integers, find out whether there are two distinct indices i and j in the array ...
- LeetCode(154) Find Minimum in Rotated Sorted Array II
题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...
- 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 ...
- LeetCode(116) Populating Next Right Pointers in Each Node
题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...
随机推荐
- 如何解决netty发送消息截断问题
在netty开发过程中我遇到过长的消息被分割成多个小消息的问题.如下图所示: 其实这两条消息应该是一条消息,它们两个才是一个完整的json字符串.查看代码原来是客户端与服务器端都没有考虑TCP粘包 ...
- 551 Student Attendance Record I 学生出勤纪录 I
给定一个字符串来代表一个学生的出勤纪录,这个纪录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场如果一个学生的出勤纪 ...
- 字符串与C51的格式化输出
一字符数组和字符指针: 字符指针可以用字符串对其直接初始化和随时赋值:而字符数组可以用字符串进行初始化,但不能用字符串对其进行随时赋值(但此时可以定义一个字符串指针指向字符数组,然后用字符串对指针随时 ...
- 51nod 1640 天气晴朗的魔法 二分 + 克鲁斯卡算法(kruskal算法) 做复杂了
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640 一开始想的时候,看到要使得最大值最小,那这样肯定是二分这个最大值了 ...
- js 中对字符串的操作
1.split() split() 方法用于把一个字符串分割成字符串数组. 用法:stringObject.split(separator,howmany) separator:必选,类型为字符串或者 ...
- httpd.exe占用100%CPU
客户VPShttpd.exe进程占用100%CPU百度搜了下,很多文章: 在网上也没有能够直接找到比较好的解决方法,后来在一个帖子上看到说,有可能是apache与其他的软件冲突了(参考http://t ...
- PHP知识点总结3
PHP 函数 PHP 的真正威力源自于它的函数. 在 PHP 中,提供了超过 1000 个内建的函数. <html> <body> <?php function writ ...
- ES-windos环境搭建(2)
下载 打开elasticsearch官网.选择downloads. 选择elasticsearch,并单击Download. 这里我们不选择最新版,而是选择靠前的版本,下拉选择past release ...
- css制作三分圆形
效果图展示: 原理很简单,主要运用transform这个样式,通过斜切和旋转达成 html: css: 怎样,是不是很简单
- list control 【转】
1. CListCtrl 风格 LVS_ICON: 为每个item显示大图标 LVS_SMALLICON: 为每个item显示小图标 LVS_LIST: 显示一列带有小图标的ite ...