Python|每日一练|字符网格匹配|数组遍历|搜索剪枝|回调函数:单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中相邻单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

 

示例 1

https://i-blog.csdnimg.cn/blog_migrate/3de3b31f000299c5b6214260a9b74b2f.jpeg

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2

https://i-blog.csdnimg.cn/blog_migrate/d66bea28c23a27faa0d26739b5559e99.jpeg

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3

https://i-blog.csdnimg.cn/blog_migrate/0c23cd5a22a1fe4844b6b60e1027f1f2.jpeg

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

 

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • board  word 仅由大小写英文字母组成

 

进阶:你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?

解题步骤

1、生成一个逻辑对照版,其组成和输入broad一致,数字位全部充填True;

2、board数组遍历i(行),j(列);

3、如果已定义了逻辑对照版且输入board中出现待匹配的word首字符,则:将对应位置的逻辑对照版修改为False;

4、调用self.check_exist对当前位置是否存在待匹配的word进行查询,并更新逻辑对照版;

5、递归后如果word可以完全匹配,返回True,不符合,返回False。

什么是剪枝

剪枝:在循环搜索的过程中,通过判断语句,剔除一些不必要的遍历过程。剪枝的主要目的是提高程序运行的效率。

请在以下选项中选择

各选项分析及解析

A

输出:fasle,错误

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        check_board = [[True] * len(board[0]) for _ in range(len(board))]
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j] == word[0] and check_board:
                    check_board[i][j] = False
                    res = self.check_exist(check_board, board, word, 1, len(word), i, j)
                    if res:
                        return True
                    check_board[i][j] = True
        return False
    def check_exist(self, check_board, board, word, index, ls, row, col):
        if index == ls:
            return True
        for temp in [(0, 1),(0, -1),(1, 0),(-1, 0)]:
            curr_row = row + temp[0]
            curr_col = col + temp[1]
            if curr_row >= 0 and curr_row < len(board) and curr_col >= 0 and curr_col < len(board[0]):
                if check_board[curr_row][curr_col] and board[curr_row][curr_col] == word[index]:
                    check_board[curr_row][curr_col] = False
                    # index - 1应为 index + 1
                    res = self.check_exist(check_board, board, word, index - 1, len(word), curr_row, curr_col)
                    if res:
                        return res
                    check_board[curr_row][curr_col] = True
        return False
if __name__ == "__main__":
    s = Solution()
    print (s.exist(board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"))

B 正确解答

输出:True

正确解答及注释

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        #生成一个逻辑对照版,其组成和输入broad一致,数字位全部充填True
        check_board = [[True] * len(board[0]) for _ in range(len(board))]
        #board数组遍历i(行),j(列)
        for i in range(len(board)):
            for j in range(len(board[0])):
                #如果已定义了逻辑对照版且输入board中出现待匹配的word首字符,则:
                if board[i][j] == word[0] and check_board:
                    #将对应位置的逻辑对照版修改为False
                    check_board[i][j] = False
                    #调用self.check_exist对当前位置是否存在待匹配的word进行查询,并更新逻辑对照版
                    res = self.check_exist(check_board, board, word, 1, len(word), i, j)
                    #如果word可以完全匹配,返回True
                    if res:
                        return True
                    #并将对照版复位,便于递归查询
                    check_board[i][j] = True
        #遍历结束后不符合,返回False
        return False
    #判断函数
    def check_exist(self, check_board, board, word, index, ls, row, col):
        #回调后index更新,与ls相比较。ls为固定值len(word),单词匹配的终止条件,
        if index == ls:
            return True
        #[(0, 1),(0, -1),(1, 0),(-1, 0)]为待匹配位置的右左下上4个维度,对这4个位置进行遍历
        for temp in [(0, 1),(0, -1),(1, 0),(-1, 0)]:
            curr_row = row + temp[0]
            curr_col = col + temp[1]
            #有效性判断,同时满足:curr_row 存在(curr_row >= 0)且 行位置未越界(curr_row < len(board) )
            #且 curr_col 存在(curr_col >= 0)且 行位置未越界(curr_col < len(board[0]) )
            if curr_row >= 0 and curr_row < len(board) and curr_col >= 0 and curr_col < len(board[0]):
                #继续剪枝,并对第2个字符(1位)字符进行判断,需满足:
                #check_board中当前位置未被使用过(初始值:True) 且  board中当前位置于待查询字符相同的条件下:
                if check_board[curr_row][curr_col] and board[curr_row][curr_col] == word[index]:
                    #变更check_board对应位置的状态为False
                    check_board[curr_row][curr_col] = False
                    #更新待查询的位置,移向下一个字符,回调函数再次进行判断。这里len(word)等价于ls
                    res = self.check_exist(check_board, board, word, index + 1, len(word), curr_row, curr_col)
                    if res:
                        return res
                    #以下语句执行不到,待增加数据测试验证
                    #check_board[curr_row][curr_col] = True
        return False
if __name__ == "__main__":
    s = Solution()
    print (s.exist(board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCFD"))

C

输出:fasle, 结果错误

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        check_board = [[True] * len(board[0]) for _ in range(len(board))]
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j] == word[0] and check_board:
                    check_board[i][j] = False
                    res = self.check_exist(check_board, board, word, 1, len(word), i, j)
                    if res:
                        return True
                    check_board[i][j] = True
        return False
    def check_exist(self, check_board, board, word, index, ls, row, col):
        if index == ls:
            return True
        for temp in [(0, 1),(0, -1),(1, 0),(-1, 0)]:
            curr_row = row + temp[0]
            curr_col = col + temp[1]
            #curr_col < 0的判断条件有误,应为:curr_col >= 0
            if curr_row < 0 and curr_row < len(board) and curr_col < 0 and curr_col < len(board[0]):
                if check_board[curr_row][curr_col] and board[curr_row][curr_col] == word[index]:
                    check_board[curr_row][curr_col] = False
                    res = self.check_exist(check_board, board, word, index + 1, len(word), curr_row, curr_col)
                    if res:
                        return res
                    check_board[curr_row][curr_col] = True
        return False
if __name__ == "__main__":
    s = Solution()
    print (s.exist(board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"))

D

输出:True,

结果正确,但代码有误

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        check_board = [[True] * len(board[0]) for _ in range(len(board))]
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j] == word[0] and check_board:
                    check_board[i][j] = False
                    res = self.check_exist(check_board, board, word, 1, len(word), i, j)
                    if res:
                        return True
                    check_board[i][j] = True
        return False
    def check_exist(self, check_board, board, word, index, ls, row, col):
        if index == ls:
            return True
        for temp in [(0, 1),(0, -1),(1, 0),(-1, 0)]:
            curr_row = row + temp[0]
            #应为:curr_col = col - temp[1],与curr_row同向变化
            curr_col = col - temp[1]
            if curr_row >= 0 and curr_row < len(board) and curr_col >= 0 and curr_col < len(board[0]):
                if check_board[curr_row][curr_col] and board[curr_row][curr_col] == word[index]:
                    check_board[curr_row][curr_col] = False
                    res = self.check_exist(check_board, board, word, index + 1, len(word), curr_row, curr_col)
                    if res:
                        return res
                    check_board[curr_row][curr_col] = True
        return False
if __name__ == "__main__":
    s = Solution()
    print (s.exist(board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值