标签:array backtracking leetcode depth-first 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
,"SEE"
,
-> returns true
,word = "ABCB"
,
-> returns false
.
思路:我们首先分析问题,如何去找匹配的字符串,第一步先是从数组中找到匹配word第一个字符的位置,接下来就是在这个位置的四个方向(上下左右)递归搜索,看是否有匹配word的字符串,如果这些位置中的字母和word下一个字母相等,则从这些位置继续搜索。我们每次从一个元素出发时,对board中的元素已访问的标志可以设一个访问标志数组,也可以把已访问的元素设置为某个特殊字符,该题中设为”#“,如果搜索失败,我们需要恢复这个字母,虽然单次搜索字符不能重复,但是每次从一个新的元素出发,这个字符还是可以使用的。
Attention:
1. 为了节省搜索的时间成本,我们应该在递归前判断当前节点的上下左右节点是否符合条件(坐标条件,以及字符匹配条件),否何才进行进一步递归。
AC Code:
//上 if(i-1 >= 0 && board[i-1][j] == word[index+1]) if(exist_helper(board, word, i-1, j, index+1)) return true;Error Code: 进入下一次递归,才进行判断,导致超时。
//如果i,j不在board范围内,并且不符合条件,则返回false if(i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || used[i][j] || board[i][j] != word[index]) return false; used[i][j] = true; bool res; res = exist_helper(board, word, i-1, j, index+1, used) || exist_helper(board, word, i+1, j, index+1, used) || exist_helper(board, word, i, j-1, index+1, used) || exist_helper(board, word, i, j+1, index+1, used);2. 这道题,字母不能重复使用,我们可以选择设置标志数组,或把字母设为特殊字符,这样可以保证无法匹配(如果再次搜索到这个字母),同时节省空间和时间,最后记得如果单次搜索失败(从一个字母出发),要恢复字母。我尝试了设置标志数组vector<vector<bool>> used(row, vector<bool>(col, false)); 但也超时了,目前还不理解。
char ctmp = board[i][j]; board[i][j] = '#';
//匹配不成功,需要恢复原来的字母 board[i][j] = ctmp;
//如果word的所有字符都匹配成功,index到达word.size()-1,递归结束,返回true if(index == word.size()-1) return true;
for(int i = 0; i < row; i++) { for(int j = 0; j < col; j++) { if(board[i][j] == word[0] && exist_helper(board, word, i, j, 0)) return true; } } return false;
AC Code:
class Solution { public: bool exist(vector<vector<char> > &board, string word) { if(word.size() == 0) return true; int row = board.size(); int col = board[0].size(); if(row == 0 || col == 0) return false; for(int i = 0; i < row; i++) { for(int j = 0; j < col; j++) { if(board[i][j] == word[0] && exist_helper(board, word, i, j, 0)) return true; } } return false; } private: bool exist_helper(vector<vector<char>> board, string word, int i, int j, int index) { //如果word的所有字符都匹配成功,index到达word.size()-1,递归结束,返回true if(index == word.size()-1) return true; char ctmp = board[i][j]; board[i][j] = '#'; //上 if(i-1 >= 0 && board[i-1][j] == word[index+1]) if(exist_helper(board, word, i-1, j, index+1)) return true; //下 if(i+1 < board.size() && board[i+1][j] == word[index+1]) if(exist_helper(board, word, i+1, j, index+1)) return true; //左 if(j-1 >= 0 && board[i][j-1] == word[index+1]) if(exist_helper(board, word, i, j-1, index+1)) return true; if(j+1 < board[0].size() && board[i][j+1] == word[index+1]) if(exist_helper(board, word, i, j+1, index+1)) return true; //匹配不成功,需要恢复原来的字母 board[i][j] = ctmp; return false; } };
[C++]LeetCode: 97 Word Search (深度优先搜索)
标签:array backtracking leetcode depth-first search
原文地址:http://blog.csdn.net/cinderella_niu/article/details/42740577