单词搜索题目的思路探讨与源码
单词搜索的题目如下图,该题属于数组类和回溯法的题目,主要考察对于回溯法,递归法的理解和认识,通过找出一个元素的搜索方式就可以利用递归和深度优先搜索进行解决。本文的题目作者暂时只想到一种方法,但由于其本质是三重for循环,显然不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用深度优先搜索DFS和回溯法结合的方法,假设对于二维数组的任意一个元素开始的元素,它本身如果和目标word相等的话可以继续搜索,而不相等则从下一个元素开始。那么在继续搜索的时候,它只能选择上下左右四个方向,对应的其实就是tuple里的(-1,0)、(0,1)、(1,0)、(0,-1)这四个方向,并且我们用一个集合去记录已经访问过的位置下标。从当前元素开始遍历,假设选择第一个方向(-1,0),如果新的位置下标没有被访问过的话,就继续调用搜索函数按上述步骤继续,否则如果被访问过或者超出二维数组边界,就进行返回,继续上一步骤的第二个方向的搜索。这种搜索的思想就是DFS深度优先搜索,因为需要不断的坚持一个方向去搜索,直到这个搜索完毕或者终止,然后从下一个方向继续搜索。所以按照这个思路我们的代码按照公式如下:
#喷火龙与水箭龟
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
choiceSearch = [(-1,0),(0,1),(1,0),(0,-1)]
wordLen = len(word)
flagSet = set()
rowSearch = len(board)
colSearch = len(board[0])
def checkSearch(a,b,indexPos):
resTmp = False
if(word[indexPos] != board[a][b]):
return False
if(indexPos == (wordLen-1)):
return True
flagSet.add((a,b))
for pi,pj in choiceSearch:
piNew = pi + a
pjNew = pj + b
if(0 <= piNew < rowSearch and 0 <= pjNew < colSearch):
if((piNew,pjNew) not in flagSet):
if(checkSearch(piNew,pjNew,indexPos+1)):
resTmp = True
break
flagSet.remove((a,b))
return resTmp
for iw in range(rowSearch):
for jw in range(colSearch):
if(checkSearch(iw,jw,0)):
return True
return False
从结果来说是比较一般的,因为时间复杂度其实是O(n^3) ,但是肯定可以进一步提速,希望朋友们能够多多指教,非常感谢。