Python算法题集_单词搜索

news2024/11/17 1:34:09

Python算法题集_单词搜索

  • 题22:单词搜索
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【原始矩阵状态+回溯】
    • 2) 改进版一【字典检测+原始矩阵状态+回溯】
    • 3) 改进版二【矩阵状态+回溯】
  • 4. 最优算法
  • 5. 相关资源

本文为Python算法题集之一的代码示例

题22:单词搜索

1. 示例说明

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

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

    示例 1:

    img

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

    示例 2:

    img

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

    示例 3:

    img

    输入: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
    • boardword 仅由大小写英文字母组成

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


2. 题目解析

- 题意分解

  1. 本题是在矩阵内检查是否有相邻元素组成对应单词
  2. 矩阵内每一个元素最多有4个方向,考虑到搜索进入方向,从第二个字母开始,最多有3个方向,可以用回溯法解题
  3. 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 可以使用字典进行字符检测,只有存在检测单词所有字符的矩阵才展开搜索

    2. 可以使用原始矩阵保存检测状态,也可以另外使用矩阵保存检测状态


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大【可把页面视为功能测试】,因此需要本地化测试解决数据波动问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题本地化超时测试用例自己生成,详见章节【最优算法】,代码文件包含在【相关资源】中

3. 代码展开

1) 标准求解【原始矩阵状态+回溯】

使用原始矩阵保存检测状态【当前已检测路径值设置为’'】,实现回溯

页面功能测试,马马虎虎,超过76%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 def exist_base(self, board, word):
     def dfs_backtrack(irow, icol, icheckpos):
         if not 0 <= irow < len(board) or not 0 <= icol < len(board[0]) or \
                 board[irow][icol] != word[icheckpos]:
             return False
         if icheckpos == len(word) - 1:
             return True
         board[irow][icol] = ''
         result = dfs_backtrack(irow + 1, icol, icheckpos + 1) or \
                  dfs_backtrack(irow - 1, icol, icheckpos + 1) or \
                  dfs_backtrack(irow, icol + 1, icheckpos + 1) or \
                  dfs_backtrack(irow, icol - 1, icheckpos + 1)
         board[irow][icol] = word[icheckpos]
         return result
     for irow in range(len(board)):
         for icol in range(len(board[0])):
             if board[irow][icol] == word[0] and dfs_backtrack(irow, icol, 0):
                 return True
     return False

aSolution = Solution()
checkmapmatrix = copy.deepcopy(mapmatrix)
result = cfp.getTimeMemoryStr(aSolution.exist_base, checkmapmatrix, checkword)
print(result['msg'], '执行结果 = {}'.format(result['result']))
 
# 运行结果
函数 exist_base 的运行时间为 24.00 ms;内存使用量为 684.00 KB 执行结果 = True

2) 改进版一【字典检测+原始矩阵状态+回溯】

使用字典进行字符集检测,符合要求的才开始回溯;回溯中使用原始矩阵保存检测状态

页面功能测试,性能卓越,超越95%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 def exist_ext1(self, board, word):
     def preCheck():
         preDict = {}
         for chr in word:
             if chr in preDict:
                 preDict[chr] += 1
             else:
                 preDict[chr] = 1
         for arow in board:
             for achr in arow:
                 if achr in preDict and preDict[achr] > 0:
                     preDict[achr] -= 1
         for aval in preDict.values():
             if aval > 0:
                 return False
         return True
     def dfs_backtrack(irow, icol, icheckpos):
         if icheckpos == imaxlen:
             return True
         if 0 <= irow < imaxrow and 0 <= icol < imaxcol and board[irow][icol] == word[icheckpos]:
             board[irow][icol] = ''
             for inextrow, inextcol in (irow, icol + 1), (irow, icol - 1), \
                     (irow + 1, icol), (irow - 1, icol):
                 if dfs_backtrack(inextrow, inextcol, icheckpos + 1):
                     return True
             board[irow][icol] = word[icheckpos]
         return False
     if preCheck() == False:
         return False
     imaxrow, imaxcol, imaxlen = len(board), len(board[0]), len(word)
     for irow in range(imaxrow):
         for icol in range(imaxcol):
             if board[irow][icol] == word[0] and dfs_backtrack(irow, icol, 0):
                     return True
     return False

aSolution = Solution()
checkmapmatrix = copy.deepcopy(mapmatrix)
result = cfp.getTimeMemoryStr(aSolution.exist_ext1, checkmapmatrix, checkword)
print(result['msg'], '执行结果 = {}'.format(result['result']))
 
# 运行结果
函数 exist_ext1 的运行时间为 25.01 ms;内存使用量为 644.00 KB 执行结果 = True

3) 改进版二【矩阵状态+回溯】

使用多维列表结构保存检测路径状态,实现回溯

页面功能测试,性能良好,超过88%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 def exist_ext2(self, board, word):
     imaxrow, imaxcol, imaxlen = len(board), len(board[0]), len(word)
     path = [''] * imaxlen
     map_check = [[False] * imaxcol for x in range(imaxrow)]
     def dfs_backtrack(icheckpos, irow, icol, imaxrow, imaxcol, board, word, checkmatrix):
         if irow < 0 or irow >= imaxrow or icol < 0 or icol >= imaxcol:
             return False
         if checkmatrix[irow][icol]:
             return False
         if board[irow][icol] != word[icheckpos]:
             return False
         if icheckpos == imaxlen - 1:
             return True
         path[icheckpos] = word[icheckpos]
         checkmatrix[irow][icol] = True
         if dfs_backtrack(icheckpos + 1, irow - 1, icol, imaxrow, imaxcol, board, word, checkmatrix) or \
            dfs_backtrack(icheckpos + 1, irow + 1, icol, imaxrow, imaxcol, board, word, checkmatrix) or \
            dfs_backtrack(icheckpos + 1, irow, icol - 1, imaxrow, imaxcol, board, word, checkmatrix) or \
            dfs_backtrack(icheckpos + 1, irow, icol + 1, imaxrow, imaxcol, board, word, checkmatrix):
             return True
         checkmatrix[irow][icol] = False
         path[icheckpos] = ''
         return False
     for irow in range(imaxrow):
         for icol in range(imaxcol):
             if dfs_backtrack(0, irow, icol, imaxrow, imaxcol, board, word, map_check):
                 return True
     return False

aSolution = Solution()
checkmapmatrix = copy.deepcopy(mapmatrix)
result = cfp.getTimeMemoryStr(aSolution.exist_ext2, checkmapmatrix, checkword)
print(result['msg'], '执行结果 = {}'.format(result['result']))
 
# 运行结果
函数 exist_ext2 的运行时间为 43.01 ms;内存使用量为 384.00 KB 执行结果 = True

4. 最优算法

根据本地日志分析,最优算法为第1种方式【原始矩阵状态+回溯】exist_base

本题测试数据,似乎能推出以下结论:

  1. 字典过滤检测性能消耗极小
  2. 额外的数据存储,带来额外的性能消耗
  3. 在检测集合和字符串多样化的情况下,第二种算法其实是会表现更好
import random, copy
imaxrow, imaxcol, checkword = 500, 300, ''
mapmatrix=[['' for x in range(imaxcol)] for y in range(imaxrow)]
words = list('abcdefghijklmnopqrstuvwxyz')
for irow in range(imaxrow):
    for icol in range(imaxcol):
        mapmatrix[irow][icol] = random.choice(words)
for iIdx in range(1, min(imaxrow, imaxcol)):
    checkword += mapmatrix[imaxrow-iIdx][imaxcol-iIdx] + mapmatrix[imaxrow-iIdx][imaxcol-iIdx-1]
aSolution = Solution()
checkmapmatrix = copy.deepcopy(mapmatrix)
result = cfp.getTimeMemoryStr(aSolution.exist_base, checkmapmatrix, checkword)
print(result['msg'], '执行结果 = {}'.format(result['result']))
checkmapmatrix = copy.deepcopy(mapmatrix)
result = cfp.getTimeMemoryStr(aSolution.exist_ext1, checkmapmatrix, checkword)
print(result['msg'], '执行结果 = {}'.format(result['result']))
checkmapmatrix = copy.deepcopy(mapmatrix)
result = cfp.getTimeMemoryStr(aSolution.exist_ext2, checkmapmatrix, checkword)
print(result['msg'], '执行结果 = {}'.format(result['result']))

# 算法本地速度实测比较
函数 exist_base 的运行时间为 24.00 ms;内存使用量为 684.00 KB 执行结果 = True
函数 exist_ext1 的运行时间为 25.01 ms;内存使用量为 644.00 KB 执行结果 = True
函数 exist_ext2 的运行时间为 43.01 ms;内存使用量为 384.00 KB 执行结果 = True

5. 相关资源

本文代码已上传到CSDN,地址:Python算法题源代码_LeetCode(力扣)_单词搜索

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

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

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

相关文章

鸿蒙开发案例:进京赶考(5)完结

系列文章目录 鸿蒙开发案例&#xff1a;进京赶考&#xff08;1&#xff09; 鸿蒙开发案例&#xff1a;进京赶考&#xff08;2&#xff09; 鸿蒙开发案例&#xff1a;进京赶考&#xff08;3&#xff09; 鸿蒙开发案例&#xff1a;进京赶考&#xff08;4&#xff09; 鸿蒙开…

ifcplusplus 示例 函数中英文 对照分析以及流程图

有需求&#xff0c;需要分析 ifc c渲染&#xff0c;分析完&#xff0c;有 230个函数&#xff0c;才能完成一个加载&#xff0c;3d加载真的是大工程&#xff01; 示例代码流程图 函数中英文对照表&#xff0c;方便 日后开发&#xff0c;整理思路顺畅&#xff01;&#xff01;&am…

KubeSphere平台安装系列之三【Linux多节点部署KubeSphere】(3/3)

**《KubeSphere平台安装系列》** 【Kubernetes上安装KubeSphere&#xff08;亲测–实操完整版&#xff09;】&#xff08;1/3&#xff09; 【Linux单节点部署KubeSphere】&#xff08;2/3&#xff09; 【Linux多节点部署KubeSphere】&#xff08;3/3&#xff09; **《KubeS…

个人项目介绍2:地球卫星篇

项目需求&#xff1a; 在项目中显示三维地球及主要城市标注&#xff0c;接收服务端发来的实施卫星数据&#xff0c;显示卫星姿态角&#xff0c;陀螺角&#xff0c;飞轮等数据&#xff1b;可自定义模拟产生更多卫星轨迹&#xff1b;可模拟显示卫星躲避陨石动画&#xff1b;可展…

【文献管理】zotero插件4——获取知网pdf、中文文献识别与目录生成

文章目录 zotero获取知网PDFzotero——中文文献识别&#xff08;茉莉花插件&#xff09;学位论文目录生成 zotero获取知网PDF zotero——中文文献识别&#xff08;茉莉花插件&#xff09; 为下载的学位论文添加目录中文文献识别&#xff1a;jasminum 下载pdflabs下载茉莉花插…

标准库中的String类 String(C++)【3】

文章目录 String常用的接口&#xff08;黑框标记的是常用接口&#xff09;数据访问operator:at:back:front: 数据修改push_back:append:operator:assigen:insert:erase:replace:注意事项 String常用的接口&#xff08;黑框标记的是常用接口&#xff09; 数据访问 operator: 返…

智能物联时代下RFID技术在汽车零部件智能制造中的引领作用

RFID&#xff08;Radio Frequency Identification&#xff0c;射频识别&#xff09;技术在汽车零部件加工中有广泛的应用&#xff0c;其工作原理是通过无线电频率进行自动识别。在汽车零部件加工中&#xff0c;RFID技术可以发挥重要作用&#xff0c;提高生产效率、降低成本和减…

【5G 接口协议】GTP-U协议介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

【虚拟机安装centos7后找不到网卡问题】

最近开始学习linux&#xff0c;看着传智播客的教学视频学习&#xff0c;里面老师用的是centos6.5&#xff0c;我这边装的是centos7最新版的 结果到了网络配置的这一节&#xff0c;卡了我好久。 我在centos一直找不到我的网卡eth0&#xff0c;只有一个回环网口&#xff0c;在/…

集成2.5G/5G/10G高速率网络变压器的RJ45网口连接器产品特点介绍

Hqst华轩盛(石门盈盛)电子导读&#xff1a;集成2.5G/5G/10G高速率网络变压器的RJ45网口连接器产品特点介绍&#xff1a; 第一、 高速率&#xff1a;支持高达2.5Gbps、5Gbps和10Gbps的传输速率&#xff0c;能够满足高带宽的网络应用需求。 第二、 集成2.5G/5G/10G高速率网…

编写dockerfile挂载卷、数据容器卷

编写dockerfile挂载卷 编写dockerfile文件 [rootwq docker-test-volume]# vim dockerfile1 [rootwq docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "------end------" CMD /bin/bash [rootwq dock…

Spring框架相关问题

Spring框架相关问题 一、Spring容器中的Bean是线程安全的吗&#xff1f;二、如何保证Spring容器中的Bean是线程安全的呢&#xff1f;三、什么情况下会触发Spring事务回滚&#xff1f;四、如果事务方法抛出IOException&#xff0c;是否会触发Spring事务回滚&#xff1f;五、什么…

在线简历制作网站免费推荐收藏备用

今天给大家推荐一个很实用的网站&#xff0c;对于要毕业的同学或者说跳槽的朋友比较有作用&#xff0c;对&#xff0c;就是一个免费方便的在线简历制作网站。其实免费的简历制作网站很多&#xff0c;但好用的良心的其实并不多&#xff0c;今天要推荐的这个虽然模板不算多&#…

1.2 在卷积神经网络中,如何计算各层感受野的大小

1.2 在卷积神经网络中&#xff0c;如何计算各层感受野的大小 分析与解答&#xff1a; 在卷积神经网络中&#xff0c;由于卷积的局部连接性&#xff0c;输出特征图上的每个节点的取值&#xff0c;是由卷积核在输入特征图对应位置的局部区域内进行卷积而得到的&#xff0c;因此这…

sql注入之sqli-labs/less-3 单引号加括号闭合

输入单引号试探&#xff1a; id1 报错信息里面出现 ) 说明闭合符合里面还有个 ) 再次试探&#xff1a;id1 ) order by 3 -- 查看回显位置&#xff1a; id-1%20%27)%20union%20select%201,2,3%20-- 查看数据库&#xff1a; id-1%20%27)%20union%20select%201,2,database()%2…

PDF 解析问题调研

说点真实的感受 &#xff1a;网上看啥组件都好&#xff0c;实际测&#xff0c;啥组件都不行。效果好的不开源收费&#xff0c;开源的效果不好。测试下来&#xff0c;发现把组件融合起来&#xff0c;还是能不花钱解决问题的&#xff0c;都是麻烦折腾一些。 这里分享了目前网上能…

幻兽帕鲁专用服务器搭建之Linux部署配置教程

大家好我是飞飞&#xff0c;上一期我分享了Windows系统的幻兽帕鲁服务器搭建教程。因为幻兽帕鲁这游戏对服务器的配置有一定的要求&#xff0c;很多小伙伴就寻思用Linux系统搭建占用会不会小一点&#xff1f;有计算机基础的小伙伴都知道Linux系统和Windows系统相比&#xff0c;…

Git实战(2)

git work flow ------------------------------------------------------- ---------------------------------------------------------------- 场景问题及处理 问题1&#xff1a;最近提交了 a,b,c,d记录&#xff0c;想把b记录删掉其他提交记录保留&#xff1a; git reset …

Hololens 2应用开发系列(2)——MRTK基础知识及配置文件配置(上)

Hololens 2应用开发系列&#xff08;2&#xff09;——MRTK基础知识及配置文件配置 一、前言二、MRTK基础知识2.1 MRTK概述2.2 MRTK运行逻辑2.3 MRTK配置文件介绍2.4 MRTK服务 三、配置文件使用3.1 总配置文件3.2 相机配置3.3 其他配置 参考文献 一、前言 在前面的文章中&…

机器学习中类别不平衡问题的解决方案

类别不平衡问题 解决方案简单方法收集数据调整权重阈值移动 数据层面欠采样过采样采样方法的优劣 算法层面代价敏感集成学习&#xff1a;EasyEnsemble 总结 类别不平衡&#xff08;class-imbalance&#xff09;就是指分类任务中不同类别的训练样例数目差别很大的情况 解决方案…