-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
0212-word-search-ii.go
82 lines (73 loc) · 2.03 KB
/
0212-word-search-ii.go
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
type TrieNode struct {
children map[byte]*TrieNode
isWord bool
refs int
}
func (this *TrieNode) addWord(word string) {
cur := this
cur.refs += 1
for c := 0; c < len(word); c++ {
if _, ok := cur.children[word[c]]; !ok {
cur.children[word[c]] = &TrieNode{children: make(map[byte]*TrieNode)}
}
cur = cur.children[word[c]]
cur.refs += 1
}
cur.isWord = true
}
func (this *TrieNode) removeWord(word string) {
cur := this
cur.refs += 1
for c := 0; c < len(word); c++ {
if _, ok := cur.children[word[c]]; ok {
cur = cur.children[word[c]];
cur.refs -= 1
}
}
}
func findWords(board [][]byte, words []string) []string {
root := &TrieNode{children: make(map[byte]*TrieNode)}
for _, w := range words {
root.addWord(w);
}
ROWS, COLS := len(board), len(board[0])
res := make(map[string]bool)
visit := make(map[int]bool)
var dfs func(int, int, *TrieNode, string)
dfs = func(r, c int, node *TrieNode, word string) {
if
r < 0 || r >= ROWS ||
c < 0 || c >= COLS ||
node.children[board[r][c]] == nil ||
node.children[board[r][c]].refs < 1 ||
visit[r*COLS + c] {
return
}
visit[r*COLS + c] = true
node = node.children[board[r][c]]
word += string(board[r][c])
if node.isWord {
node.isWord = false
res[word] = true
root.removeWord(word)
}
dfs(r + 1, c, node, word)
dfs(r - 1, c, node, word)
dfs(r, c + 1, node, word)
dfs(r, c - 1, node, word)
visit[r*COLS + c] = false
}
for r := 0; r < ROWS; r++ {
for c := 0; c < COLS; c++ {
dfs(r, c, root, "")
}
}
return list(res)
}
func list(mapping map[string]bool) []string {
res := make([]string, 0, len(mapping))
for key, _ := range mapping {
res = append(res, key)
}
return res
}