【2025刷题笔记】- 单词搜索

刷题笔记合集🔗

单词搜索

问题描述

找到它是一个小游戏,你需要在一个矩阵中找到给定的单词。

假设给定单词 HELLOWORD,在矩阵中只要能找到 H->E->L->L->O->W->O->R->L->D 连成的单词,就算通过。

注意区分英文字母大小写,并且您只能上下左右行走,不能走回头路。

输入格式

输入第 行包含两个整数 分别表示 列的矩阵,

行是长度不超过 的单词 (在整个矩阵中给定单词 只会出现一次),

从第 行到第 行是指包含大小写英文字母的长度为 的字符串矩阵。

输出格式

如果能在矩阵中连成给定的单词,则输出给定单词首字母在矩阵中的位置(第几行 第几列),

否则输出"NO"。

样例输入

5 5
HELLOWORLD
CPUCY
EKLQH
CHELL
LROWO
DGRBC
5 5
HELLOWORLD
CPUCY
EKLQH
CHELL
LROWO
AGRBC

样例输出

3 2
NO

数据范围

样例 解释说明
样例1 在矩阵中可以找到 HELLOWORLD 单词路径,起始位置在第3行第2列(即字符'H'的位置)
样例2 在矩阵中找不到形成 HELLOWORLD 的路径,所以输出"NO"
  • 单词 的长度不超过
  • 矩阵中包含大小写英文字母

题解

这道题目是一个经典的矩阵搜索问题,要求在字母矩阵中找到一条能形成目标单词的路径。

具体来说,题目要求:

  1. 在一个n×m的字母矩阵中,寻找是否存在一条路径,使得路径上的字母依次连起来刚好形成给定的单词
  2. 路径只能沿上下左右四个方向移动,且不能重复经过同一个位置
  3. 如果找到这样的路径,输出起始位置(第几行第几列);否则输出"NO"

解决这类问题的标准做法是回溯搜索(DFS):

  1. 遍历矩阵中的每个位置,尝试将其作为起点
  2. 对于每个起点,如果当前字符与单词的第一个字符匹配,则开始深度优先搜索
  3. 在搜索过程中,从当前位置向四个方向探索,寻找匹配单词下一个字符的相邻位置
  4. 使用一个visited数组来标记已经访问过的位置,避免重复访问
  5. 如果能够匹配完整个单词,则找到了答案;否则回溯并尝试其他路径

时间复杂度分析:假设矩阵大小为n×m,单词长度为k,最坏情况下需要尝试矩阵中的每个位置作为起点,每个起点至多探索4^k条路径(因为每一步有4个可能的方向),因此总时间复杂度为O(n×m×4^k)。但实际上,由于剪枝(只有匹配的字符才会继续搜索)和路径不能重复的限制,算法效率会比理论上限好很多。

在本题给定的数据范围内(n,m<21,单词长度≤100),这个解法在实际应用中是高效的。

参考代码

  • Python
import sys

# 定义输入函数
input = lambda: sys.stdin.readline().strip()

# 读取输入
n, m = map(int, input().split())  # 矩阵的行数和列数
word = input()  # 目标单词
matrix = [input() for _ in range(n)]  # 字母矩阵

# 四个方向的偏移量:上、右、下、左
directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]

def search_word():
    # 记录已访问的位置
    visited = [[False for _ in range(m)] for _ in range(n)]
    
    # 深度优先搜索函数
    def dfs(row, col, index):
        # 如果已经匹配完整个单词,返回True
        if index == len(word):
            return True
        
        # 如果当前位置越界、已访问或字符不匹配,返回False
        if (row < 0 or row >= n or col < 0 or col >= m or 
            visited[row][col] or matrix[row][col] != word[index]):
            return False
        
        # 标记当前位置为已访问
        visited[row][col] = True
        
        # 在四个方向上继续搜索
        for dr, dc in directions:
            if dfs(row + dr, col + dc, index + 1):
                return True
        
        # 回溯:将当前位置标记为未访问
        visited[row][col] = False
        return False
    
    # 尝试矩阵中的每个位置作为起点
    for i in range(n):
        for j in range(m):
            if dfs(i, j, 0):
                # 找到路径,返回起始位置(题目要求是1-indexed)
                return f"{i+1} {j+1}"
    
    # 没有找到符合条件的路径
    return "NO"

# 输出结果
print(se

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

2025-12-27 20:52
已编辑
快手_MLOps(实习员工)
和干燥的的北方不同,杭州的12月是湿润的,白天从工位一抬头,雾霭已经笼罩了整个园区,从写字楼的落地窗看出去,如置身仙境。不敢高声语,恐惊天上人今天是周六,去公司坐了一会儿,一是想趁着周末工区比较安静学习一会儿,二是去健身房锻炼一会儿完美的结束这一天之后我和往常一样,走在创景路上,看着远处的恒生科技园,西溪永乐城,以及最远处的挂着火山引擎四个大字的写字楼,头戴式耳机默默放着《Sacred&nbsp;Play&nbsp;Secret&nbsp;Place&nbsp;》空灵的旋律让路程没有那么枯燥,心中默默计算着还有多久可以到家周末没有晚高峰,往常车水马龙的路口显得格外冷清,和往常走在同样路线的我,看到了对面走来了一个小哥未见其人先问其声小哥:“不好意思打扰一下,你能帮帮我吗”我:???小哥:“我来这边打工的,我现在身上没钱了,没地方住也没吃饭,可以问你借一点钱吗,300就可以,我已经被很多人拒绝了”我看着他眼睛,心里很想给他转这笔钱,但就在我想转账的时候,我突然想到,如果他是骗子呢?我也不过是一个初入社会的学生,如果他真的是骗子,最后让我身无分文,杭州还会像我现在看到的这样美好吗?犹豫片刻我说:“这样吧我带你去买一点吃的吃可以吗?”他说不用了,还没有走远,就听到他对刚过来马路的两个女生开启了同样的对话,我没有留下来继续听,只是继续保持着原有的路线。他是骗子吗,也许是。我应该给他转这笔钱吗,应该吧,万一他真的很需要呢?小时候看过的文学和影视作品,主角总会是一个乐观,有点呆呆的大男孩,被人卖了还会帮别人数钱。圣母心泛滥。但这样的人身上的坚持,执拗和善良恰恰经常打动年幼的我,我想或许未来我也会成为这样的人,止于至善。但现在我知道了小时候动画片里只有一个敌人,主角打败BOSS就可以皆大欢喜。但现在我知道,生活里四面八方都是敌人,我也不一定是主角,一山更比一山高,不管怎么选都有可能走到一个BE的结局所以做一个不那么善良,利己一点的人,不去当一个大家喜闻乐见,社会需要的人有问题吗?没有一丁点问题,或许我们成为不了热血漫男主,但在我们的生活中,我们可以成为自己快走到家门口的时候,看到烧烤店的老板娘还在招待着零星几个客人,不远处字节的写字楼还亮着灯“也许刚才我可以换点现金给他,这样就不会被有骗的风险了,算了,他有手有脚的,凭什么要让我接济”耳机里的歌已经换成了《Be&nbsp;What&nbsp;You&nbsp;Wanna&nbsp;Be》Dorin略带沙哑的嗓音洗去了刚才心中的一点点迷茫上高中的时候,我的语文老师告诉我,想让文章变得高级,就要在文章中尽量减少“我”这样的字眼出现,这样你的文章分数才会更高但在这个世界,“我”却不可或缺,生活的评分标准也不会白纸黑字的摆在你面前了,也许不能成为耀眼的男主角,但可以成为你自己今日方知我是我
牛客解忧铺
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务