掘金团队号上线,助你 Offer 临门! 点击 查看详情
单词搜索 II(题号212)
题目
给定一个 m x n
二维字符网格 board
和一个单词(字符串)列表 words
,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例 1:
输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]
示例 2:
输入:board = [["a","b"],["c","d"]], words = ["abcb"]
输出:[]
提示:
m == board.length
n == board[i].length
1 <= m, n <= 12
board[i][j]
是一个小写英文字母1 <= words.length <= 3 * 104
1 <= words[i].length <= 10
words[i]
由小写英文字母组成words
中的所有字符串互不相同
链接
解释
这一题虽然是困难,但感觉困难在想法上,具体内容其实并不复杂。
重点就是字典树和递归的联合用法,先拿到字典树,之后遍历整个board
,遇到合适的直接开始遍历。
遍历可能比较不好理解,其实就是拿到字典树的节点开始一层层遍历,由于字典树可能有多个分叉,需要在分叉中继续遍历,那么此时就需要在已有单词的时候将已有单词添加进res
,注意此时不能停止遍历,应该继续遍历,否则剩余的分叉无法被遍历到,导致失败,
总的来说就是字典树的分叉和递归的分叉合到一起了,正常人很难想到的。
自己的答案
无
更好的方法(字典树)
var findWords = function(board, words) {
var res = []
row = board.length
col = board[0].length
trie = {}
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
for (const word of words) {
var node = trie
for (const chart of word) {
if (!node[chart]) node[chart] = {}
node = node[chart]
}
node.word = word
}
function findChart(root, i ,j) {
if (root.word) {
res.push(root.word)
root.word = null
}
if (i >= row || j >= col || i < 0 || j < 0) return
if (!root[board[i][j]]) return
var currentChart = board[i][j]
board[i][j] = false
for (let k = 0; k < 4; k++) {
findChart(root[currentChart], i + dx[k], j + dy[k])
}
board[i][j] = currentChart
return
}
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++) {
findChart(trie, i, j)
}
}
return res
};
PS:想查看往期文章和题目可以点击下面的链接:
这里是按照日期分类的👇
经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇
有兴趣的也可以看看我的个人主页👇