Leetcode 079 搜索单词 Python C++ 史上最详细题解系列
2018-08-16 09:07
731 查看
题目:
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] 给定 word = "ABCCED", 返回 true. 给定 word = "SEE", 返回 true. 给定 word = "ABCB", 返回 false.
每天更新一道python or C++ leetcode题,力求讲解清晰准确,客官们可以点赞或者关注。
算法过程:(主要见代码注释)
1.通过search函数的参数x, y记录当前搜索的位置,同时遍历上下左右方向,进入下一个位置。进入时要考虑下个位置是否符合标准。(详细解释见代码)
2.已搜索过的位置记为true,防止递归无法终止。搜索完后重新标记为false。
代码:
python:(看着吓人,实际逻辑很简单)
[code]class Solution: def __init__(self): self.pos = list()# self.n = self.m = 0#用来储存行和列的数目 self.flag = False#用来标志最终结果 self.l = 0#单词长度 self.target = ""#目标要构建的单词 self.direction = [[1,0],[-1,0],[0,1],[0,-1]]#可以选的方向 def search(self, board, x, y, s): if s == self.target: self.flag = True; return#如果构建中的字符串达到目标要构建的单词 if len(s) >= self.l: return#如果构建的字符的长度大了,就返回,防止无限增加 self.pos[x][y] = True#把当前位置标记为已搜索,防止再次搜索。 for d in self.direction:#遍历所有方向,上下左右 if 0 <= x+d[0] <= self.n-1 and 0 <= y+d[1] <= self.m-1 and not self.pos[x+d[0]][y+d[1]] and board[x+d[0]][y+d[1]] == self.target[len(s)]:#只有当下个节点没有超过边界并且没有被访问过并且是下一个必须的组成单词的下一个字母时,我们才调用递归 self.search(board, x+d[0], y+d[1], s+board[x+d[0]][y+d[1]])#构建中的单词需要加上下一个字母,同时更新位置 if self.flag: return#如果找到了该单词,直接返回 self.pos[x][y] = False#把当前标为未访问 def exist(self, board, word): self.n = len(board)#储存行数 if self.n == 0: return False self.m = len(board[0])#储存列数 if self.m == 0: return False self.l = len(word)#储存单词长度 if self.l == 0 or self.l > self.n*self.m: return False#如果当前单词比所有字母连一起还长 self.target = word#储存目标单词 self.pos = [[False for col in range(self.m)] for row in range(self.n)]#构建一个检测有没有被访问的表 for i in range(self.n): for j in range(self.m): if board[i][j] == word[0]:#如果当前字母等于第一个字母,开始递归 self.search(board,i,j,board[i][j]) return self.flag#返回最终结果
C++(写的相对简洁一点)
[code]class Solution { public: bool exist(vector<vector<char>>& board, string word) { int row = board.size(); int col = board[0].size(); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { //visit数组记录该数组是否被访问过 vector<vector<bool>> visit(row, vector<bool>(col, false)); bool res = dfs(board, visit, i, j, word, 0); if (res == true) return true; } } return false; } //index表示的是当前探索的是第几个词 bool dfs(vector<vector<char>>& b, vector<vector<bool>>& visit, int x, int y, //遍历数组的每一点 string s, int index) { int row = b.size(); int col = b[0].size(); if (index == s.length()) return true; //以下几种情况 不再进行处理 //1、数组越界 //2、该节点已经访问过 //3、index位置的字符与字符串中的字符不符 else if (x < 0 || x >= row || y < 0 || y >= col //1 || visit[x][y] == true //2 || s[index]!=b[x][y]) //3 return false; else { visit[x][y] = true; //从xy出发向周围进行探索 bool x_1y = dfs(b, visit, x - 1, y, s, index + 1); bool x1y = dfs(b, visit, x + 1, y, s, index + 1); bool xy_1 = dfs(b, visit, x, y - 1, s, index + 1); bool xy1 = dfs(b, visit, x, y + 1, s, index + 1); if (x_1y || x1y || xy_1 || xy1) return true; else { visit[x][y] = false; return false; } } } };
总结:
1.DFS可以通过记录当前位置来达到深搜目的
2.用visited 数组可以防止重复搜索,无法结束递归
3.注意剪枝
阅读更多相关文章推荐
- Leetcode 81 搜索旋转排序数组 II Python C++ 史上最详细题解系列
- Leetcode 80 删除排序数组中的重复项 II Python C++ 史上最详细题解系列
- Leetcode 83 删除排序链表中的重复元素 Python C++ 史上最详细题解系列
- Leetcode 82 删除排序链表中的重复元素 II Python C++ 史上最详细题解系列
- Leetcode 312 打气球 Burst Balloons C++ 史上最详细题解系列
- 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】
- LeetCode题解汇总(C++ Java Python,含题目翻译)
- leetcode_效率题解_[python/C++]_147. Insertion Sort List(链表插入排序)
- [LeetCode]题解(python):079-Word Search
- leetcode_效率题解_[python/C++]_21. Merge Two Sorted Lists(合并2个有序链表)
- 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】
- [LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql)
- 【脚本语言系列】关于Python代码包/代码库搜索,你需要知道的事
- LeetCode 7 — Reverse Integer(C++ Java Python)
- Leetcode 题解系列(二)
- [LeetCode]题解(python):102- Binary Tree Level Order Traversal
- LeetCode 19 — Remove Nth Node From End of List(C++ Java Python)
- [LeetCode]题解(python):032-Longest Valid Parentheses
- [LeetCode] 031. Next Permutation (Medium) (C++/Python)
- 判断字符串是否能分割成字典中的单词(二)——Leetcode系列(十二)