79.单词搜索 python

题目

题目描述

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

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

示例 1:

在这里插入图片描述

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

示例 2:

在这里插入图片描述

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

示例 3:

在这里插入图片描述

输入: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 更大的情况下可以更快解决问题?

题解

这个问题可以通过深度优先搜索(DFS)来解决。对于每个起始点,我们尝试沿着四个方向(上、下、左、右)进行递归搜索,检查是否可以找到匹配的单词路径。为了避免重复使用同一个单元格,我们需要在进入递归时标记当前单元格为已访问,并在退出递归时恢复其状态。

以下是 Python 实现:

def exist(board, word):
    if not board or not board[0]:
        return False

    rows, cols = len(board), len(board[0])

    def dfs(r, c, index):
        # 如果索引达到了单词的长度,说明已经找到了完整的单词
        if index == len(word):
            return True

        # 检查边界条件和字符匹配
        if r < 0 or r >= rows or c < 0 or c >= cols or board[r][c] != word[index]:
            return False

        # 标记当前单元格为已访问
        temp, board[r][c] = board[r][c], '#'

        # 尝试向四个方向递归搜索
        found = (dfs(r + 1, c, index + 1) or
                 dfs(r - 1, c, index + 1) or
                 dfs(r, c + 1, index + 1) or
                 dfs(r, c - 1, index + 1))

        # 恢复当前单元格的状态
        board[r][c] = temp

        return found

    # 尝试从每个单元格开始搜索
    for r in range(rows):
        for c in range(cols):
            if dfs(r, c, 0):
                return True

    return False

进阶优化:搜索剪枝

为了提高效率,可以在搜索过程中加入一些剪枝策略:

  1. 提前终止:如果在任何时刻发现当前路径不可能形成目标单词,则立即返回 False
  2. 预处理:检查网格中是否包含所有需要的字符,以及每个字符的数量是否足够。如果缺少任何一个字符或某个字符的数量不足,则直接返回 False
  3. 反向搜索:如果单词的前缀比后缀更频繁出现于网格中,考虑反转单词进行搜索。
  4. 优化起点选择:优先从那些唯一性较高的字符作为起点开始搜索,减少不必要的遍历。

通过这些优化措施,我们可以显著减少不必要的计算,使算法在更大的输入规模下表现更好。例如,在实际应用中,可以根据具体的数据分布情况调整搜索策略,以获得最佳性能。

提交结果

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

gxls2024

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

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

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

打赏作者

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

抵扣说明:

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

余额充值