-
Notifications
You must be signed in to change notification settings - Fork 0
/
212-word-search-ii.js
95 lines (73 loc) · 1.93 KB
/
212-word-search-ii.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// https://leetcode.com/problems/word-search-ii/
/**
* @param {character[][]} board
* @param {string[]} words
* @return {string[]}
*/
var findWords = function (board, words) {
const root = new Node('^')
for (const word of words) {
root.addChild(word + '$')
}
const set = new Set()
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
for (const item of traverse(board, i, j, root, '')) {
set.add(item)
}
}
}
return Array.from(set.values())
};
function traverse(board, i, j, node, word) {
const result = []
const value = board[i][j]
const nextNode = node.children[value]
if (!nextNode) {
return result
}
const nextWord = word + value
if (nextNode.children['$']) {
result.push(nextWord)
}
const hasTop = i > 0 && board[i - 1][j] !== '_'
const hasBottom = i < board.length - 1 && board[i + 1][j] !== '_'
const hasLeft = j > 0 && board[i][j - 1] !== '_'
const hasRight = j < board[i].length - 1 && board[i][j + 1] !== '_'
if (!hasTop && !hasBottom && !hasLeft && !hasRight) {
return result
}
const nextBoard = [
...board.slice(0, i),
[...board[i].slice(0, j), '_', ...board[i].slice(j + 1)],
...board.slice(i + 1)
]
if (hasTop) {
result.push(...traverse(nextBoard, i - 1, j, nextNode, nextWord))
}
if (hasBottom) {
result.push(...traverse(nextBoard, i + 1, j, nextNode, nextWord))
}
if (hasLeft) {
result.push(...traverse(nextBoard, i, j - 1, nextNode, nextWord))
}
if (hasRight) {
result.push(...traverse(nextBoard, i, j + 1, nextNode, nextWord))
}
return result
}
function Node(value) {
this.value = value
this.children = {}
}
Node.prototype.addChild = function (word) {
const value = word.slice(0, 1)
let child = this.children[value]
if (!child) {
child = new Node(value)
this.children[value] = child
}
if (word.length > 1) {
child.addChild(word.slice(1))
}
}