这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true
示例 3:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false
链接:leetcode-cn.com/problems/wo…
题解
这道题目是二维的搜索类题目,一般方法就是 dfs + 回溯。
dfs 需要的变量有当前的棋盘坐标 x,y,当前 word 的下标,以及一个 used 数组,用于判断对应的位置是否被使用过。
dfs 的递归终止条件有以下几个:
- i === word.length 也就是 word 的所有字符已经都找到了,可以返回 true
- x < 0 || x >= m || y < 0 || y >= n 也就是坐标在棋盘之外,返回 false
- used[x][y] === true 对应的坐标字符已经被使用过,不能再被使用,返回 false
- board[x][y] !== word[i] 对应的坐标字符和 word 的字符不相等,返回 false
注意递归完成后,需要将 used 数组恢复原状,也就是回溯。
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
var exist = function(board, word) {
const m = board.length
const n = board[0].length
let used = Array.from({ length: m }, () => (new Array(n).fill(false)))
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (board[i][j] === word[0]) {
const res = dfs(i, j, 0, board, word, used)
if (res) return true
}
}
}
return false
}
var dfs = (x, y, i, board, word, used) => {
if (i === word.length) return true
if (x < 0 || y < 0 || x >= board.length || y >= board[0].length)
return false
if (used[x][y]) return false
if (board[x][y] !== word[i]) return false
used[x][y] = true
// 递归寻找
const res = dfs(x+1, y, i+1, board, word, used) || dfs(x-1, y, i+1, board, word, used) || dfs(x, y+1, i+1, board, word, used) || dfs(x, y-1, i+1, board, word, used)
// 回溯
used[x][y] = false
return res
}