[LeetCode] Word Search 的非递归实现
来源:互联网 发布:it技术总监岗位职责 编辑:程序博客网 时间:2024/05/17 17:40
真是孤陋寡闻,直到前些时间才知道有LeetCode这么一个网站。这段时间我正好也在复习数据结构,这样可以用这些题来检验一下学习效果。就从Array分类的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.
思路还是很容易想到的,先通过二重循环找到地一个字母的位置,然后做深度优先搜索(4个方向),参照书上深度优先搜索的递归实现,改一改,调试调试,就通过了。源码如下
class Solution(object): def __init__(self): self._next = [(1,0),(0,1),(-1,0),(0,-1)] def _dfs(self, x, y): if self._flag == True: return if self._count == len(self._word): self._flag = True return for i in range(4): tx, ty = x + self._next[i][0], y + self._next[i][1] if 0<=tx<self._row and 0<=ty<self._col and \ self._visited[tx][ty] == 0 and \ self._board[tx][ty] == self._word[self._count]: self._visited[tx][ty] = 1 self._count += 1 self._dfs(tx,ty) self._count -= 1 self._visited[tx][ty] = 0 def exist(self, board, word): """ :type board: List[List[str]] :type word: str :rtype: bool """ self._row = len(board) #row self._col = len(board[0]) #col self._visited = [[0 for j in range(self._col) ] for i in range(self._row) ] self._board = board self._word = word self._count = 0 self._flag = False for row in range(self._row): for col in range(self._col): if self._board[row][col] == self._word[0]: self._visited[row][col] = 1 self._count = 1 self._dfs(row,col) if self._flag == True: return True self._visited[row][col] = 0 self._count = 0 return Falseif __name__ == '__main__': s = Solution() board = ["ABCE","SFES","ADEE"] word = "ABCESEEEFS" print s.exist(board,word) board = ["ABCE","SFCS","ADEE","ADEE","ADEE","ADEE"] word = "ABCS" print s.exist(board,word)因正好在看堆栈相关的内容,所以想用非递归来实现。原来以为能够比较轻松搞定,结果确实比较狼狈,反反复复,把周六、周日都搭上了,最后总算通过。收获是通过这个程序把一些原来没有弄得很清楚的地方理清楚了。即什么时候入栈,什么时候出栈,把什么东西放到堆栈里。对应这个问题,就是什么时候向前走(深度优先),什么时候回退( backtrace),回退到哪一步。
入栈的内容:[x, y, steps ],其中x, y是当前满足要求的节点的坐标,steps是一个列表,存放与(x,y)的四个方向上的邻居节点,前提是这些邻居节点是下一个满足要求的字母。如果没有满足邻居节点,则steps为空,则出栈;如果不为空,则从steps.pop()一个(tx, ty)出来判断,如果(tx, ty)有符合要求邻居节点的则(tx, ty)如站,否则继续从steps.pop(),然后继续判断;如果直到堆栈为空,还没有找到,则返回False,找到返回True。找的过程中必须标记以访问的点,这些点不能再次访问,否则重复了。
代码如下:
class Solution(object): def _push(self, e): self._stack.append(e) def _pop(self): if len(self._stack)>0: return self._stack.pop() #remove last item from list else: return None def _top(self): if len(self._stack)>0: return self._stack[-1] else: return None def _dfs(self, x, y): if x<0 or y<0: return False if self._word[0] == self._board[x][y]: self._visited[x][y] = 1 self._count = 1 if self._count == len(self._word): return True steps = [] for i in range(3, -1, -1): tx, ty = x + self._next[i][0], y + self._next[i][1] if 0<= tx < self._row and 0<= ty < self._col and \ self._visited[tx][ty] == 0 and \ self._word[self._count] == self._board[tx][ty]: #self._visited[tx][ty] = 1 steps.append((tx,ty)) self._push([x,y,steps]) #print '---' else: return False while self._top() != None: #print self._stack #print self._count e = self._top() x, y, steps = e[0], e[1], e[2] if len(steps) == 0: #backtrace self._visited[x][y] = 0 self._count -= 1 self._pop() else: #forward x, y = steps.pop() #if self._word[self._count] == self._board[x][y]: self._count += 1 self._visited[x][y] = 1 if self._count == len(self._word): return True else: tsteps = [] for i in range(3, -1, -1): tx, ty = x + self._next[i][0], y + self._next[i][1] if 0<= tx < self._row and 0<= ty < self._col and \ self._visited[tx][ty] == 0 and \ self._word[self._count] == self._board[tx][ty]: #self._visited[tx][ty] = 1 tsteps.append((tx,ty)) if len(tsteps) == 0: #backtrace self._visited[x][y] = 0 self._count -= 1 else: self._push([x,y,tsteps]) #forward return False def exist(self, board, word): """ :type board: List[List[str]] :type word: str :rtype: bool """ self._next = [(1,0),(0,1),(-1,0),(0,-1)] self._row = len(board) #row self._col = len(board[0]) #col self._visited = [[0 for j in range(self._col) ] for i in range(self._row) ] self._board = board self._word = word self._stack = [] #the stack self._count = 0 for x in range(self._row): for y in range(self._col): self._count = 0 if self._board[x][y] == self._word[0]: if self._dfs(x,y) : return True return Falseif __name__ == '__main__': s = Solution() board = ["ABCE","SFES","ADEE"] #word = "ABCESEEEFS" word = 'ABCESEEEFS' print s.exist(board,word) board = ["ABCE123456","SFCS123456","ADEE123456","ADEE123456","ADEE123456","ADEE123456"] word = "ABCB" print s.exist(board,word) word = "ABCA" print s.exist(board,word) board = ["ABCE","SFCS","ADEE"]
LeetCode 有一个好处,提交的程序不通过,它会把测试不通过的测试数据告诉你,这样就方便调试了。构造测试用例真的很重要。
- [LeetCode] Word Search 的非递归实现
- leetcode解题之35#Search Insert Position Java版 递归和非递归实现
- leetcode 二叉树前序遍历的递归和非递归实现
- leetcode 二叉树中序遍历的递归和非递归实现
- leetcode 35. Search Insert Position-二分查找|递归|非递归
- 二叉搜索树(Binary Search Tree)的递归和非递归代码实现(C++)
- 二叉搜索树(Binary Search Tree)的递归和非递归代码实现(C++)
- [C++]LeetCode: 93 Binary Search Tree Iterator (经典题,非递归的中序遍历)
- 【LeetCode】递归和非递归的区别
- leetcode 二叉树遍历非递归实现
- LeetCode: Word Search
- [Leetcode] Word Search
- LeetCode : Word Search
- Leetcode: Word Search
- [LeetCode] Word Search
- leetcode 56: Word Search
- Leetcode 79 Word Search
- [leetcode ] word search
- aws简单开发之ec2定时开关机
- vc CEdit类控件的使用
- C语言版通讯录
- 机器学习实战之 Logistic算法
- li怎么清除li的样式
- [LeetCode] Word Search 的非递归实现
- 资深操盘手独家总结隐藏在K线背后的奥秘
- Android中canvas和paint的关系及使用
- js实现页面重复出现的banner和footer部分
- 智能导航短信告警的一个逻辑处理
- android快速开发的技巧
- Eclipse 快捷键整理
- Android 记录和恢复ListView滚动的位置的三种方法
- win32API 读写ANSI\UNICODE\UNICODE BIG-ENDIAN\UTF-8格式文本