[JavaScript 刷题] 树 - 单词搜索 II, leetcode 212
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] 树 - 单词搜索 II, leetcode 212相关的知识,希望对你有一定的参考价值。
[javascript 刷题] 树 - 单词搜索 II, leetcode 212
github repo 地址: https://github.com/GoldenaArcher/js_leetcode,Github 的目录 大概 会更新的更勤快一些。
题目地址:212. 单词搜索 II
题目
如下:
Given an
m x n
board of characters and a list of stringswords
, return all words on the board.Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
解题思路
这道题的前置题是 79. Word Search,79 主要用的技巧就是 backtracking,但是如果只用 backtracking 的话,这道题就会超时。
暴力解的时间复杂度为
O
(
w
×
m
×
n
×
4
l
)
O(w \\times m \\times n \\times 4^l)
O(w×m×n×4l),其中
4
l
4^l
4l 是每个单词遍历所需时间,
l
l
l 代表单词的平均长度;
w
w
w 代表单词的数量。总体的理解就是说,每一次遍历 grid[row][col]
的时候都查找一下所有的单词,去看单词是否有可能包含在当前的单词搜索路径中。
Trie 简述在 前缀树 trie 中有提到,简单地说,使用前缀树可以将时间按复杂度从 O ( w × m × n × 4 l ) O(w \\times m \\times n \\times 4^l) O(w×m×n×4l) 降到 O ( m × n × 4 l ) O(m \\times n \\times 4^l) O(m×n×4l),因为每次遍历的时候就可以查看当前单词是否存在于 trie 中,如果不在还可以提前中断遍历。
用之前画的 trie 举例,下面的 trie 由这个数组构成:['apart', 'app', 'ape', 'apathetical', 'apathy']
.。
当在一个 m × n m \\times n m×n 的二维数组中搜索这些单词的时候,只需要遍历 trie 一次就能够判断当前单词是否存在于单词列表中,而不需要遍历整个数组。
便利的过程就是 79. Word Search 的核心算法:backtracking。
使用 JavaScript 解题
我不知道为什么 if (node.word) res.add(node.word);
这里直接返回了,这就导致一些单词找不到……
嗯……
还debug了很久,这个需要注意一下,如果 ad
找到了,还是需要继续寻找 add
的,直接返回就会中断搜索。
/**
* @param character[][] board
* @param string[] words
* @return string[]
*/
class TreeNode
constructor(val)
this.val = val;
this.children = [];
this.word = null;
getIdx(ch)
return ch.charCodeAt(0) - "a".charCodeAt(0);
addChild(word)
let root = this;
for (const ch of word)
const idx = this.getIdx(ch);
if (!root.children[idx]) root.children[idx] = new TreeNode(ch);
root = root.children[idx];
root.word = word;
isChild(ch)
const idx = this.getIdx(ch);
return this.children[idx] !== undefined;
getChild(ch)
const idx = this.getIdx(ch);
return this.children[idx];
var findWords = function (board, words)
const root = new TreeNode(""),
ROWS = board.length,
COLS = board[0].length,
res = new Set(),
directions = [
[0, 1],
[0, -1],
[1, 0],
[-1, 0],
];
for (const word of words)
root.addChild(word);
const dfs = (r, c, node, letter) =>
if (
r < 0 ||
c < 0 ||
r === ROWS ||
c === COLS ||
!board[r][c] ||
!node.isChild(letter)
)
return;
board[r][c] = "#";
node = node.getChild(letter);
if (node.word) res.add(node.word);
for (const [ri, ci] of directions)
if (!board[r + ri]) continue;
dfs(r + ri, c + ci, node, board[r + ri][c + ci]);
board[r][c] = letter;
;
for (let i = 0; i < ROWS; i++)
for (let j = 0; j < COLS; j++) dfs(i, j, root, board[i][j]);
return Array.from(res);
;
以上是关于[JavaScript 刷题] 树 - 单词搜索 II, leetcode 212的主要内容,如果未能解决你的问题,请参考以下文章
[JavaScript 刷题] 搜索 - 单词搜索, leetcode 79
[JavaScript 刷题] 搜索 - 单词搜索, leetcode 79
[JavaScript 刷题] 搜索 - 单词搜索, leetcode 79
[JavaScript 刷题] 搜索 - 最短单词路径, leetcode 127