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
二、思路分析
- 第一反应就是dfs处理该题目,dfs参数为
i,j,k,i为当前行,j为当前列,k为字符串中符合的字符下标。 - 递归终止条件,如果k ≥ word的长度,则说明当前字符串可以在矩阵中被遍历到。条件2,如果i<0或者j<0 表明访问坐标小于下界,会越界异常,如果i ≥n或者j≥m,则访问坐标大于上界,发生越界异常,如果board[i][j] ≠ word[k],则说明当前遍历的坐标不匹配字符串中的字符,返回false。
- 遍历到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]。