[C++]LeetCode: 97 Word Search (深度优先搜索)
来源:互联网 发布:淘宝如何解除实名认证 编辑:程序博客网 时间:2024/05/17 07:05
题目:
word =
3. 由于我们每次先判断了四个方向的字母是否匹配word[index+1],匹配才进入下一层递归,所以迭代终止条件是如果index达到word.size()-1. 表明word字符都匹配成功,返回true. 如果选择index == word.size()终止, 当index = word.size()-1时,接下来调用word[index+1]会指针越界。
4. 这道题设计很巧妙的地方,就是我们在主函数中遍历寻找匹配word第一个字母的位置,解下来从这个位置出发进行递归搜索,搜索成功,返回true. 递归函数只是在四个方向递归搜索,出发位置是在主函数中确定的。
复杂度:最坏的情况,我们需要对每一个顶点都搜索一遍,总的时间复杂度O(M^2 * N^2)
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
.
思路:我们首先分析问题,如何去找匹配的字符串,第一步先是从数组中找到匹配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;
3. 由于我们每次先判断了四个方向的字母是否匹配word[index+1],匹配才进入下一层递归,所以迭代终止条件是如果index达到word.size()-1. 表明word字符都匹配成功,返回true. 如果选择index == word.size()终止, 当index = word.size()-1时,接下来调用word[index+1]会指针越界。
//如果word的所有字符都匹配成功,index到达word.size()-1,递归结束,返回true if(index == word.size()-1) return true;
4. 这道题设计很巧妙的地方,就是我们在主函数中遍历寻找匹配word第一个字母的位置,解下来从这个位置出发进行递归搜索,搜索成功,返回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;
复杂度:最坏的情况,我们需要对每一个顶点都搜索一遍,总的时间复杂度O(M^2 * N^2)
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; }};
0 0
- [C++]LeetCode: 97 Word Search (深度优先搜索)
- leetcode 79. Word Search DFS深度优先遍历
- 深度优先搜索(Depth-First-Search)
- 深度优先搜索(deep first search)
- 深度优先搜索(Depth-First-Search,DFS)
- LeetCode上Tag为深度优先搜索(Depth-frist Search)的题目整理
- leetcode 98. Validate Binary Search Tree DFS深度优先搜索 + 一个错误做法
- leetcode 669. Trim a Binary Search Tree 修建二叉搜索树BST + 深度优先遍历DFS
- leetcode 140. Word Break II 动态规划DP + DFS深度优先搜索
- Beam Search 基础知识-广度优先及深度优先搜索
- 【C++】【LeetCode】79. Word Search
- leetcode:深度优先搜索(DFS)和广度优先搜索(BFS)
- LeetCode 127 Word Ladder (广度优先搜索)
- LeetCode随笔之DFS深度优先搜索
- leetcode 78. Subsets DFS深度优先搜索
- Leetcode Word Search搜索文中单词
- C/C++: 邻接矩阵 深度优先搜索
- 图的深度优先搜索 c代码
- map使用方法
- (转AS3)使用闭包给事件监听附带参数
- 对涂胶工艺认识的误区之七——一种涂胶机可以做出各种所需宽度的胶条
- 致我们的后青春
- Cocos2d-x扣血飘字特效用完你就消失--之游戏开发《赵云要格斗》(8)
- [C++]LeetCode: 97 Word Search (深度优先搜索)
- Financial Management
- tar命令
- shell文件操作(删除,显示,查找,增加,替换) sed用法
- 40个迹象表明你还是PHP菜鸟(转载)
- Hadoop添加删除节点
- Hibernate 配置文件
- Android 亮度调节
- 解决Hi-Tcc更新联系人页面crash问题