11
11
class WordSearchII {
12
12
13
13
func findWords( _ board: [ [ Character ] ] , _ words: [ String ] ) -> [ String ] {
14
- var res = [ String] ( )
15
-
16
- let m = board. count
17
- let n = board [ 0 ] . count
18
-
19
- let trie = _convertToTrie ( words)
20
- var visited = [ [ Bool] ] ( repeating: Array ( repeating: false , count: n) , count: m)
21
-
22
- for i in 0 ..< m {
23
- for j in 0 ..< n {
24
- _dfs ( board, m, n, i, j, & visited, & res, trie, " " )
14
+ let trie = Trie ( words) , m = board. count, n = board [ 0 ] . count
15
+ var isVisited = Array ( repeating: Array ( repeating: false , count: n) , count: m) , res = Set < String > ( )
16
+
17
+ for i in 0 ..< m {
18
+ for j in 0 ..< n {
19
+ search ( board, trie, & res, i, j, & isVisited, trie. root, " " , m, n)
25
20
}
26
21
}
27
-
28
- return res
22
+
23
+ return Array ( res)
29
24
}
30
25
31
- fileprivate func _dfs( _ board: [ [ Character ] ] , _ m: Int , _ n: Int , _ i: Int , _ j: Int , _ visited: inout [ [ Bool ] ] , _ res: inout [ String ] , _ trie: Trie , _ str: String ) {
32
- // beyond matrix
26
+ private func search( _ board: [ [ Character ] ] , _ trie: Trie , _ res: inout Set < String > , _ i: Int , _ j: Int , _ isVisited: inout [ [ Bool ] ] , _ currentNode: TrieNode , _ currentStr: String , _ m: Int , _ n: Int ) {
33
27
guard i >= 0 && i < m && j >= 0 && j < n else {
34
28
return
35
29
}
36
-
37
- // check visited
38
- guard !visited[ i] [ j] else {
30
+
31
+ guard !isVisited[ i] [ j] else {
39
32
return
40
33
}
41
-
42
- // check is word prefix
43
- let str = str + " \( board [ i] [ j] ) "
44
- guard trie. isWordPrefix ( str) else {
34
+
35
+ guard let child = currentNode. children [ board [ i] [ j] ] else {
45
36
return
46
37
}
47
-
48
- // check word exist
49
- if trie. isWord ( str) && !res. contains ( str) {
50
- res. append ( str)
38
+
39
+ isVisited [ i] [ j] = true
40
+
41
+ let str = currentStr + " \( board [ i] [ j] ) "
42
+
43
+ if child. isEnd {
44
+ res. insert ( str)
51
45
}
52
-
53
- // check four directions
54
- visited [ i] [ j] = true
55
- _dfs ( board, m, n, i + 1 , j, & visited, & res, trie, str)
56
- _dfs ( board, m, n, i - 1 , j, & visited, & res, trie, str)
57
- _dfs ( board, m, n, i, j + 1 , & visited, & res, trie, str)
58
- _dfs ( board, m, n, i, j - 1 , & visited, & res, trie, str)
59
- visited [ i] [ j] = false
46
+
47
+ search ( board, trie, & res, i + 1 , j, & isVisited, child, str, m, n)
48
+ search ( board, trie, & res, i - 1 , j, & isVisited, child, str, m, n)
49
+ search ( board, trie, & res, i, j + 1 , & isVisited, child, str, m, n)
50
+ search ( board, trie, & res, i, j - 1 , & isVisited, child, str, m, n)
51
+
52
+ isVisited [ i] [ j] = false
60
53
}
61
54
62
- func _convertToTrie( _ words: [ String ] ) -> Trie {
63
- let trie = Trie ( )
64
-
65
- for str in words {
66
- trie. insert ( str)
55
+ class Trie {
56
+ var root : TrieNode
57
+
58
+ init ( _ words: [ String ] ) {
59
+ root = TrieNode ( )
60
+
61
+ words. forEach { insert ( $0) }
67
62
}
68
-
69
- return trie
70
- }
71
- }
72
-
73
-
74
- class Trie {
75
- var root : TrieNode
76
-
77
- init ( ) {
78
- root = TrieNode ( )
79
- }
80
-
81
- func insert( _ word: String ) {
82
- var node = root
83
- var word = [ Character] ( word. characters)
84
-
85
- for i in 0 ..< word. count {
86
- let c = word [ i]
87
-
88
- if node. children [ c] == nil {
89
- node. children [ c] = TrieNode ( )
63
+
64
+ private func insert( _ word: String ) {
65
+ var node = root
66
+
67
+ for char in word {
68
+ if node. children [ char] == nil {
69
+ node. children [ char] = TrieNode ( )
70
+ }
71
+
72
+ node = node. children [ char] !
90
73
}
91
-
92
- node = node . children [ c ] !
74
+
75
+ node. isEnd = true
93
76
}
94
-
95
- node. isEnd = true
96
77
}
97
-
98
- func isWord( _ word: String ) -> Bool {
99
- var node = root
100
- var word = [ Character] ( word. characters)
101
-
102
- for i in 0 ..< word. count {
103
- let c = word [ i]
104
-
105
- if node. children [ c] == nil {
106
- return false
107
- }
108
-
109
- node = node. children [ c] !
110
- }
111
78
112
- return node. isEnd
113
- }
79
+ class TrieNode {
80
+ var isEnd : Bool
81
+ var children : [ Character : TrieNode ]
114
82
115
- func isWordPrefix( _ prefix: String ) -> Bool {
116
- var node = root
117
- var prefix = [ Character] ( prefix. characters)
118
-
119
- for i in 0 ..< prefix. count {
120
- let c = prefix [ i]
121
-
122
- if node. children [ c] == nil {
123
- return false
124
- }
125
-
126
- node = node. children [ c] !
83
+ init ( ) {
84
+ isEnd = false
85
+ children = [ Character: TrieNode] ( )
127
86
}
128
-
129
- return true
130
87
}
131
88
}
132
-
133
- class TrieNode {
134
- var isEnd : Bool
135
- var children : [ Character : TrieNode ]
136
-
137
- init ( ) {
138
- isEnd = false
139
- children = [ Character: TrieNode] ( )
140
- }
141
- }
0 commit comments