【Python3】 LeetCode 7月挑战题目之21 - Word Search

第二十一天问: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 and word 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

Reference/参考资料

https://blog.csdn.net/fuxuemingzhu/article/details/79386066

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值