📌  相关文章
📜  检查是否可以使用矩阵的相邻单元格的字符形成给定的字符串(1)

📅  最后修改于: 2023-12-03 15:26:47.616000             🧑  作者: Mango

检查矩阵是否可以形成给定字符串

有一个字符矩阵和一个给定的字符串,检查是否可以使用该矩阵中相邻单元格的字符形成给定的字符串。

示例

输入

矩阵:

a b c e
s f c s
a d e e

给定字符串:"abcced"

输出

true

解释:该矩阵中相邻单元格的字符可以形成字符串 "abcced"

解法

暴力搜索

首先思考暴力搜索的方法。

我们可以遍历矩阵中的每一个字符,以该字符为起点,尝试匹配给定字符串。

匹配方法为:以该字符为起点,按照字符串的顺序,依次匹配相邻单元格的字符。

如果成功匹配整个字符串,返回 true

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m, n = len(board), len(board[0])
        visited = set()
        def dfs(i, j, k):
            if k == len(word):
                return True
            if i < 0 or i >= m or j < 0 or j >= n:
                return False
            if (i, j) in visited or board[i][j] != word[k]:
                return False
            visited.add((i, j))
            res = 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.remove((i, j))
            return res
        for i in range(m):
            for j in range(n):
                if dfs(i, j, 0):
                    return True
        return False

DFS遍历

我们可以使用 DFS 遍历整个字符矩阵。

遍历方法为:以字符矩阵中的每个位置依次为起点,使用 DFS 遍历所有可能的路径,每遍历一个节点判断是否符合要求。

为了避免重复遍历同一个节点,我们需要使用一个 visited 集合记录已经遍历过的节点。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m, n = len(board), len(board[0])
        visited = set()
        def dfs(i, j, k):
            if k == len(word):
                return True
            if i < 0 or i >= m or j < 0 or j >= n:
                return False
            if (i, j) in visited or board[i][j] != word[k]:
                return False
            visited.add((i, j))
            res = 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.remove((i, j))
            return res
        for i in range(m):
            for j in range(n):
                if dfs(i, j, 0):
                    return True
        return False

BFS遍历

我们也可以使用 BFS 遍历整个字符矩阵。

遍历方法为:以字符矩阵中的每个位置依次为起点,使用 BFS 遍历所有可能的路径,每遍历一个节点判断是否符合要求。

相比于 DFS,BFS 更适合找到最短路径。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m, n = len(board), len(board[0])
        visited = set()
        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
        queue = []
        for i in range(m):
            for j in range(n):
                if board[i][j] == word[0]:
                    queue.append((i, j, 0))
        while queue:
            i, j, k = queue.pop(0)
            if k == len(word)-1:
                return True
            visited.add((i, j))
            for d in directions:
                x, y = i+d[0], j+d[1]
                if 0 <= x < m and 0 <= y < n and board[x][y] == word[k+1] and (x, y) not in visited:
                    queue.append((x, y, k+1))
        return False
参考文献
  1. LeetCode 79. Word Search