-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path212-word-search-ii.swift
66 lines (59 loc) · 1.83 KB
/
212-word-search-ii.swift
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
class TrieNode {
var children = [Character: TrieNode]()
var isWord = false
var refs = 0
func append(_ word: String) {
var curr: TrieNode = self
curr.refs += 1
for c in word {
curr.children[c] = curr.children[c] ?? TrieNode()
curr = curr.children[c]!
curr.refs += 1
}
curr.isWord = true
}
func remove(_ word: String) {
var curr = self
for c in word {
guard let child = curr.children[c] else { continue }
child.refs -= 1
curr = child
}
}
}
class Solution {
func findWords(_ board: [[Character]], _ words: [String]) -> [String] {
var result = [String]()
var visited = Set<[Int]>()
let rows = board.count
let cols = board[0].count
func dfs(_ r: Int, _ c: Int, _ node: TrieNode, _ word: String) {
if r == -1 || r == rows ||
c == -1 || c == cols ||
visited.contains([r, c]) { return }
guard let nextNode = node.children[board[r][c]], nextNode.refs > 0 else { return }
let word = word + "\(board[r][c])"
if nextNode.isWord {
nextNode.isWord = false
result.append(word)
trie.remove(word)
}
visited.insert([r, c])
dfs(r - 1, c, nextNode, word)
dfs(r + 1, c, nextNode, word)
dfs(r, c - 1, nextNode, word)
dfs(r, c + 1, nextNode, word)
visited.remove([r, c])
}
let trie = TrieNode()
for word in words {
trie.append(word)
}
for r in 0..<rows {
for c in 0..<cols {
dfs(r, c, trie, "")
}
}
return result
}
}