亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

LeetCode 79. 單詞搜索 | Python

標簽:
Python 算法

79. 单词搜索


题目


给定一个二维网格和一个单词,找出该单词是否存在于网格中。

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

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false

提示:

  • board 和 word 中只包含大写和小写英文字母。
  • 1 <= board.length <= 200
  • 1 <= board[i].length <= 200
  • 1 <= word.length <= 10^3

解题思路


思路:深度优化搜索、回溯

首先看题意,题目中要求单词必须按照字母顺序,在给定的二维数组中,找到单词。可通过相邻单元格的字母组成,这里【相邻】包括横向和纵向相邻的单元格,这里就涉及到一个偏移量的问题,但是同一个单元的字母不能够重复使用。

先看下如何去实现搜索?首先我们要先要对二维数组进行遍历,要先找到跟单词首字母相同的元素,这里要注意,当找到这个元素时,要先进行标记,因为题意要求字母不能重复使用。

当找到这个元素时,从当前元素的位置开始进行搜索,需要往四个方位进行搜索,看看相邻的单元格元素是否是单词的下一个字母,这里分为两种情况:

  • 能够匹配时,从这个元素继续进行搜索
  • 不能匹配时,返回 False,这里要进行回溯

当所有的字母完全匹配时,则返回 True。

具体的实现代码如下。

代码实现


class Solution:
    directions = [(1, 0), (0, -1), (-1, 0), (0, 1)]

    def exist(self, board: List[List[str]], word: str) -> bool:
        if len(board) == 0:
            return False
        
        # 四个方位偏移量
        

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

        # 这里用以标记元素是否使用
        # False 表示未使用
        # True 表示已使用
        marked = [[False for _ in range(cols)] for _ in range(rows)]

        # 先遍历,
        for row in range(rows):
            for col in range(cols):
                    # 当找到所有元素时返回 True
                    if self._search(row, col, board, word, 0, marked):
                        return True
        return False

    def _search(self, i, j, board, word, index, marked):
        # 终止条件
        if index == len(word) - 1:
            return board[i][j] == word[index]

        # 只有匹配了才继续搜索
        if board[i][j] == word[index]:
            # 这里先标记元素,如果搜索不成功的情况下,解除标记
            marked[i][j] = True
            # 四个方位搜索
            for dx, dy in self.directions:
                nrow = i + dx
                ncol = j + dy

                # 限定边界,
                # 搜索时找相邻未使用过的元素
                if 0 <= nrow < len(board) and 0 <= ncol < len(board[0]) and not marked[nrow][ncol] and self._search(nrow, ncol, board, word, index + 1, marked):
                    return True
            # 释放标记
            marked[i][j] = False
        return False

实现结果


实现结果

总结


  • 使用深度优先搜索 + 回溯的思路,解决此题;
  • 首先定位单词首元素,找到对应的位置之后,由此从四个方位继续搜索;
  • 搜索的同时,要先标记当前元素为已使用,防止后面定位的元素搜索时重复使用;
  • 如果某个搜索路线未找到单词时,要进行回溯,将此次标记的元素全部释放。

點擊查看更多內容
1人點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消