春招打卡|矩阵中的路径

87 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

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

二、思路分析

  1. 第一反应就是dfs处理该题目,dfs参数为i,j,k,i为当前行,j为当前列,k为字符串中符合的字符下标。
  2. 递归终止条件,如果k ≥ word的长度,则说明当前字符串可以在矩阵中被遍历到。条件2,如果i<0或者j<0 表明访问坐标小于下界,会越界异常,如果i ≥n或者j≥m,则访问坐标大于上界,发生越界异常,如果board[i][j] ≠ word[k],则说明当前遍历的坐标不匹配字符串中的字符,返回false。
  3. 遍历到board[i][j]后,将其修改为*号,避免重复dfs,再在dfs后将其修改为原始字符,避免影响其他dfs过程,dfs分别为行数+1,行数-1,列数+1,列数-1,每个k都为k+1表示遍历字符串后一个字符。

三、AC 代码

func exist(board [][]byte, word string) bool {
    n,m := len(board),len(board[0])
    if n * m < len(word) {
        return false
    }
    var dfs func(i,j,k int) bool
    dfs = func(i,j,k int) bool {
        if k >= len(word)  {
            return  true
        }
        if i <0 || i >= n || j < 0 || j >= m || word[k] != board[i][j] {
            return false
        }
        board[i][j] = '*'
        res := dfs(i+1,j,k+1) ||  dfs(i,j+1,k+1) || dfs(i-1,j,k+1) || dfs(i,j-1,k+1)
        board[i][j] = word[k]
        return res
    }
    for i := 0;i<n;i++ {
        for j := 0;j<m;j++ {
            if dfs(i,j,0){
                return true
            }
        }
    }
    return false
}

四、总结

一道普通dfs题目,注意边界条件。避免回溯时无法找到符合字符,要记得恢复board[i][j] 为word[k]。