Python面试宝典第18题:单词搜索

news2024/9/24 7:17:58

题目

        给定一个m x n的二维字符网格board和一个字符串单词word。如果word存在于网格中,返回true。否则,返回false。单词必须按照字母顺序,通过相邻的单元格内的字母构成。所谓相邻单元格,是那些水平相邻或垂直相邻的单元格。

        备注:board和word仅由大小写英文字母组成。

        注意:同一个单元格内的字母不允许被重复使用。

        示例 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

回溯法

        使用回溯法求解本题的基本思想是:深度优先搜索每一个可能的路径,同时确保沿着路径上的字符能够构成目标单词;如果发现无法构成目标单词或者已经探索完所有路径,就回溯到上一步继续尝试其他分支。关键在于控制访问状态,避免重复访问同一单元格。使用回溯法求解本题的主要步骤如下。

        1、定义一个递归函数,输入当前坐标、已访问矩阵、当前构建的单词片段。

        2、检查当前位置的字符是否与单词的当前片段匹配,如果不匹配直接返回。

        3、标记当前位置为已访问。

        4、如果当前构建的单词片段等于目标单词,返回True。

        5、对当前坐标四周的合法未访问位置递归调用该函数。

        6、如果所有方向都无法匹配成功,则回溯:取消当前位置的访问标记,返回False。

        7、遍历网格的每个单元格,调用上述递归函数开始搜索。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def board_word_search_by_backtracking(board, word):
    def dfs(i, j, k):
        if not 0 <= i < m or not 0 <= j < n or board[i][j] != word[k] or visited[i][j]:
            return False
        if k == len(word) - 1:
            return True
        visited[i][j] = True
        result = (dfs(i + 1, j, k + 1) or
                  dfs(i - 1, j, k + 1) or
                  dfs(i, j + 1, k + 1) or
                  dfs(i, j - 1, k + 1))
        visited[i][j] = False
        return result

    m, n = len(board), len(board[0])
    visited = [[False]*n for _ in range(m)]
    for i in range(m):
        for j in range(n):
            if dfs(i, j, 0):
                return True
    return False
    
board = [
    ["A", "B", "C", "E"],
    ["S", "F", "C", "S"],
    ["A", "D", "E", "E"]
]
word = "ABCCED"
print(board_word_search_by_backtracking(board, word))

广度优先搜索算法

        使用广度优先搜索(BFS)算法求解本题的基本思想是:从每个可能的起始位置开始,一层一层地扩展到其周围的邻居节点,同时跟踪已访问的位置和当前构建的单词路径;通过维护一个队列来保存待探索的节点,并使用哈希集合记录已访问状态,可以有效地避免重复访问,直到找到匹配的单词或探索完所有路径。使用广度优先搜索算法求解本题的主要步骤如下。

        1、创建一个队列用于存储待探索的节点,每个节点包含当前坐标和已构建的单词片段。

        2、遍历board,将所有与word首字符匹配的单元格作为起始节点加入队列,并记录它们的访问状态。

        3、当队列非空时,从队列中弹出节点,检查其构建的单词片段是否等于word,如果是则返回true。

        4、对于每个弹出的节点,探索其四个相邻节点。如果相邻节点未访问且字符匹配,则将新节点(包含更新的坐标和单词片段)加入队列,并标记为已访问。

        5、如果队列为空,说明所有路径都已探索但未找到匹配,返回false。

        根据上面的算法步骤,我们可以得出下面的示例代码。

from collections import deque

def board_word_search_by_bfs(board, word):
    def get_neighbors(x, y):
        for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
            nx, ny = x + dx, y + dy
            if 0 <= nx < m and 0 <= ny < n:
                yield nx, ny
                
    m, n = len(board), len(board[0])
    visited = [[False]*n for _ in range(m)]
    
    for i in range(m):
        for j in range(n):
            if board[i][j] == word[0]:
                queue = deque([(i, j, 0)])
                visited[i][j] = True
                
                while queue:
                    x, y, idx = queue.popleft()
                    if idx == len(word) - 1:
                        return True
                    
                    for nx, ny in get_neighbors(x, y):
                        if not visited[nx][ny] and board[nx][ny] == word[idx + 1]:
                            visited[nx][ny] = True
                            queue.append((nx, ny, idx + 1))
                
                for x in range(m):
                    for y in range(n):
                        visited[x][y] = False
                        
    return False

board = [
    ["A", "B", "C", "E"],
    ["S", "F", "C", "S"],
    ["A", "D", "E", "E"]
]
word = "ABCCED"
print(board_word_search_by_bfs(board, word))

总结

        两种算法的时间复杂度均为O(m * n * 4^L),其中m和n分别是网格的行数和列数,L是单词的长度。这是因为每个单元格可能触发一条路径,而每条路径最多可能有4个不同的方向可以探索。空间复杂度均为O(m * n),因为需要这么多的空间来记录已访问状态。相比回溯法,BFS在处理较宽的搜索树时通常更为高效,因为它可以更快地找到最短路径。但BFS实现相对复杂一些,需要管理队列和已访问状态的哈希集合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1944251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Blender材质-PBR与纹理材质

1.PBR PBR:Physically Based Rendering 基于物理的渲染 BRDF:Bidirection Reflectance Distribution Function 双向散射分散函数 材质着色操作如下图&#xff1a; 2.纹理材质 左上角&#xff1a;编辑器类型中选择&#xff0c;着色器编辑器 新建着色器 -> 新建纹理 -> 新…

爬虫学习3:爬虫的深度爬取

爬虫的深度爬取和爬取视频的方式 深度爬取豆瓣读书 import time import fake_useragent import requests from lxml import etree head {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 …

[AWS]MSK调用,报错Access denied

背景&#xff1a;首先MSK就是配置一个AWS的托管 kafka&#xff0c;创建完成之后就交给开发进行使用&#xff0c;开发通常是从代码中&#xff0c;编写AWS的access_key 和secret_key进行调用。 但是开发在进行调用的时候&#xff0c;一直报错连接失败&#xff0c;其实问题很简单&…

AI学习记录 - 本地知识库实现的相关知识

在公司内部实现了个知识库&#xff0c;由于保密吗&#xff0c;只介绍在实现知识库的过程中用到的知识&#xff08;虽然知识库也是个烂大街的东西了hehehehe&#xff09; 1、分词器 先分词&#xff0c;中文可以使用jieba分词 2、构造数据集 将词汇向量化是自然语言处理中的…

OpenHarmony 开发

本心、输入输出、结果 文章目录 OpenHarmony 开发前言JonathanOpenHarmony 并不是 AndroidOpenHarmony 应用迁移OpenHarmony 的开发流程OpenHarmony 开发 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助,欢迎点赞、收藏、评…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十七章 字符设备和杂项设备总结回顾

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

vim gcc

vim 使用 vs filename 分屏 ctrl ww 切窗口 shift zz 快速提出vim vim配置 vim启动时自动读取当前用户的家目录的.vimrc文件 vim配置只影响本用户 其他用户观看同一文件不受影响 gcc指令 & c文件编译过程 动态库 静态库 & 链接方式 有相应库才能进行…

数据传输安全--IPSEC

目录 IPSEC IPSEC可以提供的安全服务 IPSEC 协议簇 两种工作模式 传输模式 隧道模式 两个通信保护协议&#xff08;两个安全协议&#xff09; AH&#xff08;鉴别头协议&#xff09; 可以提供的安全服务 报头 安全索引参数SPI 序列号 认证数据 AH保护范围 传输模…

深入浅出WebRTC—LossBasedBweV2

WebRTC 同时使用基于丢包的带宽估计算法和基于延迟的带宽估计算法那&#xff0c;能够实现更加全面和准确的带宽评估和控制。基于丢包的带宽估计算法主要依据网络中的丢包情况来动态调整带宽估计&#xff0c;以适应网络状况的变化。本文主要讲解最新 LossBasedBweV2 的实现。 1…

SSIS_SQLITE

1.安装 SQLite ODBC 驱动程序 2.添加SQLite数据源 在“用户DSN”或“系统DSN”选项卡中&#xff0c;点击“添加”。选择“SQLite3 ODBC Driver”&#xff0c;然后点击“完成”。在弹出的配置窗口中&#xff0c;设置数据源名称&#xff08;DSN&#xff09;&#xff0c;并指定S…

python实现特征检测算法4

python实现Richardson-Lucy 反卷积算法 Richardson-Lucy 反卷积算法算法原理Python实现详细解释Richardson-Lucy算法的优缺点应用领域Richardson-Lucy 反卷积算法 Richardson-Lucy反卷积算法是一种迭代算法,用于恢复因成像系统中的点扩散函数(PSF)导致的模糊图像。该算法最…

Spring MVC 应用分层

1. 类名使⽤⼤驼峰⻛格&#xff0c;但以下情形例外&#xff1a;DO/BO/DTO/VO/AO 2. ⽅法名、参数名、成员变量、局部变量统⼀使⽤⼩驼峰⻛格 3. 包名统⼀使⽤⼩写&#xff0c;点分隔符之间有且仅有⼀个⾃然语义的英语单词. 常⻅命名命名⻛格介绍 ⼤驼峰: 所有单词⾸字⺟…

【LLM-推理】Self-Refine:使用feedback迭代修正LLM的Output

来源&#xff1a; https://selfrefine.info/ 1.论文速读(摘要引言) 本文主要提出了Self-Refine策略&#xff0c;旨在通过一个LLM不断refine修正LLM的输出&#xff0c;使其在无需额外训练的情况下&#xff0c;在下游任务产生更好的效果。 该方法的直观Insight&#xff1a;我们…

7.23 字符串简单中等 520 125 14 34

520 Detect Capital 思路&#xff1a; 题目&#xff1a;判定word &#xff1a;if the usage of capitals in it is right.遍历所有的string&#xff1a; 两种情况&#xff1a; 首字母capitals–>判定第二个字母是否大写–>所有字母大写 otherwise 除第一个以外全部小写&a…

Github Desktop 关于将本地文件夹设置为新仓库的 使用笔记

实际要达到的结果: 将UE5工程同步到Github,工程太大,我们只需要将必要的工程文件夹同步即可,缓存等一些不必要的文件夹则不需要同步 最终效果预览: 1. 将本地文件夹设置为新仓库 将本地文件夹作为仓库一般你是没有这个仓库的,所以你需要新建一个仓库 如果忽略某些不必要的文…

视触觉传感器在矿物/岩石识别中的应用探索

人工智能推动矿物/岩石自动识别技术的发展&#xff0c;该技术减少了人工成本和对个人经验的依赖。随着仪器仪表的数字化&#xff0c;图像识别发挥着越来越重要的作用。清华大学联合中国地质大学近期在期刊Advanced Intelligent Systems&#xff08;JCR Q1, 影响因子7.4&#xf…

JAVA.4.继承

1.特点 java只支持单继承&#xff0c;一个儿子继承一个父亲 但可以多层继承&#xff0c;a继承b&#xff0c;b继承c b是a的直接父类&#xff0c;c是a的间接父类 每个类都直接或者简介继承Object&#xff0c;不写继承就默认继承它 2.注意事项 构造方法 父类的构造方法&#…

生成式 AI 的发展方向:Chat 还是 Agent?

生成式 AI 的发展方向&#xff0c;是 Chat 还是 Agent&#xff1f; 随着生成式 AI 技术的不断进步&#xff0c;关于其未来发展方向的讨论也愈发激烈。究竟生成式 AI 的未来是在对话系统&#xff08;Chat&#xff09;中展现智慧&#xff0c;还是在自主代理&#xff08;Agent&am…

GO内存分配详解

文章目录 GO内存分配详解一. 物理内存(Physical Memory)和虚拟内存(Virtual Memory)二. 内存分配器三. TCMalloc线程内存(thread memory)页堆(page heap)四. Go内存分配器mspanmcachemcentralmheap五. 对象分配流程六. Go虚拟内存ArenaGO内存分配详解 这篇文章中我将抽丝剥茧,…

LINUX之MMC子系统分析

目录 1. 概念1.1 MMC卡1.2 SD卡1.3 SDIO 2. 总线协议2.1 协议2.2 一般协议2.3 写数据2.4 读数据2.5 卡模式2.5.1 SD卡模式2.5.2 eMMC模式 2.6 命令2.6.1 命令类2.6.2 详细命令 2.7 应答2.8 寄存器2.8.1 OCR2.8.2 CID2.8.3 CSD2.8.4 RCA2.8.5 扩展CSD 3. 关键结构3.1 struct sdh…