目录/Table of Content
第二十一天问:Word Search
这次题目首先会给你一个字母方格表和一串目标字符,然后现在需要判断出这表的字母可不可以给出目标字符。而且,这些字母只可以橫着或者竖着相连,並且不能重复使用多于一次。
大家好,我是一个喜欢研究算法、机械学习和生物计算的小青年,我的CSDN博客是:一骑代码走天涯
如果您喜欢我的笔记,那么请点一下关注、点赞和收藏。如果內容有錯或者有改进的空间,也可以在评论让我知道。😄
题目&示例 (引用自 LeetCode)
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.
Example:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
Constraints:
board
andword
consists only of lowercase and uppercase English
letters.1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3
解题思路
最开始,我是想写一个helper function帮自己判断每个格子是不是符合目标字串的字母。但是,写出来並不简洁,而且一直有一个问题,就是很难避免重复遍历这个问题,一直给不了正确答案 (写代码方面真的还是新手 TAT)。
以下就是我一开始提交的代码:
失败代码 (不完整,仅供自己存档)
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
# Define a helper function.
def move_check(i, j, word_sub, direction):
if direction == "left" and j > 0: # Move one square left.
print(word_sub, i, j, direction)
if len(word_sub) == 1 and Board[i][j-1] == word_sub:
print("Completed by left")
return True
if len(word_sub) > 1 and Board[i][j-1] == word_sub[0]:
Board[i][j-1] = Board[i][j-1].swapcase()
return (move_check(i, j-1, word_sub[1:], 'up') or \
move_check(i, j-1, word_sub[1:], 'down') or \
move_check(i, j-1, word_sub[1:], 'left'))
if Board[i][j-1] != word[0]:
print("Not left")
return False
if direction == "right" and j < (len(Board[i]) - 1): # Move one square right.
print(word_sub, i, j, direction)
if len(word_sub) == 1 and Board[i][j+1] == word_sub:
print("Completed by right")
return True
if len(word_sub) > 1 and Board[i][j+1] == word_sub[0]:
Board[i][j+1] = Board[i][j+1].swapcase()
return (move_check(i, j+1, word_sub[1:], 'right') or \
move_check(i, j+1, word_sub[1:], 'up') or \
move_check(i, j+1, word_sub[1:], 'down'))
if Board[i][j+1] != word_sub[0]:
print("Not right")
return False
if direction == "up" and i > 0: # Move one square up.
print(word_sub, i, j, direction)
if len(word_sub) == 1 and Board[i-1][j] == word_sub:
print("Completed by up")
return True
if len(word_sub) > 1 and Board[i-1][j] == word_sub[0]:
Board[i-1][j] = Board[i-1][j].swapcase()
return (move_check(i-1, j, word_sub[1:], 'right') or \
move_check(i-1, j, word_sub[1:], 'up') or \
move_check(i-1, j, word_sub[1:], 'left'))
if Board[i-1][j] != word_sub[0]:
print("Not up")
return False
if direction == "down" and i < (len(Board) - 1): # Move one square up.
print(word_sub, i, j, direction)
if len(word_sub) == 1 and Board[i+1][j] == word_sub:
print("Completed by down")
return True
if len(word_sub) > 1 and Board[i+1][j] == word_sub[0]:
Board[i+1][j] = Board[i+1][j].swapcase()
return (move_check(i+1, j, word_sub[1:], 'right') or \
move_check(i+1, j, word_sub[1:], 'down') or \
move_check(i+1, j, word_sub[1:], 'left'))
if Board[i+1][j] != word_sub[0]:
print("Not down")
return False
print("End ", direction)
return False
# Main program.
if len(board) * len(board[0]) < len(word):
return False
if len(word) == 0 or word.isspace():
return False
if word == board[0][0]:
return True
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] == word[0] and len(word) > 1:
Board = board.copy()
res = move_check(i, j, word[1:], 'right')
if res: return res
Board = board.copy()
res = move_check(i, j, word[1:], 'down')
if res: return res
Board = board.copy()
res = move_check(i, j, word[1:], 'left')
if res: return res
Board = board.copy()
res = move_check(i, j, word[1:], 'up')
if res: return res
elif board[i][j] == word:
return True
return False
实在沒辦法,我就参考了別人的代码提交了,完成了今天的練习。这里我也放了我所参考的代码,有兴趣的可以直接去链結看解释,我就不多說了。据我个人分析,时间复杂度为字母表的总大小 (列 (n) 乘以栏 (m)),空间复杂度为目标字串的长度 (k)。
参考代码 (引用自CSDN博客)
时间复杂度:O(
n
×
m
n\times m
n×m)
空间复杂度:O(
k
k
k)
class Solution(object):
def exist(self, board, word):
"""
:type board: List[List[str]]
:type word: str
:rtype: bool
"""
for y in range(len(board)):
for x in range(len(board[0])):
if self.exit(board, word, x, y, 0):
return True
return False
def exit(self, board, word, x, y, i):
if i == len(word):
return True
if x < 0 or x >= len(board[0]) or y < 0 or y >= len(board):
return False
if board[y][x] != word[i]:
return False
board[y][x] = board[y][x].swapcase()
isexit = self.exit(board, word, x + 1, y, i + 1) or self.exit(board, word, x, y + 1, i + 1) or self.exit(board, word, x - 1, y, i + 1) or self.exit(board, word, x, y - 1, i + 1)
board[y][x] = board[y][x].swapcase()
return isexit