https://leetcode.com/problems/word-search/description/
在一个二维字符矩阵中搜索是否存在给定字符串,要求只能水平或垂直搜索
思路:回溯。对每个位置遍历一遍,分别对(i,j)的上下左右位置递归。
第一种写法,对一般的测试用例能通过,但对于特别大的矩阵会报超时。
class Solution:
def exist(self, board, word):
"""
:type board: List[List[str]]
:type word: str
:rtype: bool
"""
self.length = 0 #记录匹配的串长
#遍历整个矩阵
for i in range(len(board)):
for j in range(len(board[0])):
if word[0] == board[i][j]: #找到切入点
board[i][j] = '.' #标记为已访问
self.backtrack(board, word, 1, i, j) #,从word[1]开始
board[i][j] = word[0] #还原现场
if self.length > 0:
return True
return False
#回溯函数,count为word中已找到的字符数,row、col为矩阵坐标
def backtrack(self, board, word, count, row, col):
if count == len(word): #整个串都找到
self.length = count
else:
#上
if row - 1 >= 0 and board[row - 1][col] == word[count]:
board[row - 1][col] = '.'
self.backtrack(board, word, count + 1, row - 1, col)
board[row - 1][col] = word[count]
#下
if row + 1 < len(board) and board[row + 1][col] == word[count]:
board[row + 1][col] = '.'
self.backtrack(board, word, count + 1, row + 1, col)
board[row + 1][col] = word[count]
#左
if col - 1 >= 0 and board[row][col - 1] == word[count]:
board[row][col - 1] = '.'
self.backtrack(board, word, count + 1, row, col - 1)
board[row][col - 1] = word[count]
#右
if col + 1 < len(board[0]) and board[row][col + 1] == word[count]:
board[row][col + 1] = '.'
self.backtrack(board, word, count + 1, row, col + 1)
board[row][col + 1] = word[count]
改进写法:主要改进递归函数,很多操作,例如将某个位置置‘.’和恢复现场,是可以归纳到一起的。此外也不用额外寻找‘切入点’,归纳到一起即可。
class Solution:
def exist(self, board, word):
"""
:type board: List[List[str]]
:type word: str
:rtype: bool
"""
self.length = 0
for i in range(len(board)):
for j in range(len(board[0])):
if self.backtrack(board, word, 0, i, j): #从word[0]开始
return True
return False
def backtrack(self, board, word, count, row, col):
if count == len(word):
return True
#下标越界,或者当前位置字符不匹配
if row < 0 or row >= len(board) or col < 0 or col >= len(board[0]) or board[row][col] != word[count]:
return False
#防止重复访问
board[row][col] = '.'
#对四个方向递归搜索,注意是or
res = self.backtrack(board, word, count+1, row-1, col) or self.backtrack(board, word, count+1, row+1, col) or self.backtrack(board, word, count+1, row, col-1) or self.backtrack(board, word, count+1, row, col+1)
#还原现场
board[row][col] = word[count]
return res