2
2
* Question Link: https://leetcode.com/problems/word-squares/
3
3
* Primary idea: Classic Depth-first Search, fill out row by row, choose correct word with fixed prefix, only need to care which column is used
4
4
*
5
- * Time Complexity: O(n^n ), Space Complexity: O(n)
5
+ * Time Complexity: O(n^2 ), Space Complexity: O(n^2 )
6
6
*
7
7
*/
8
8
9
9
class WordSquares {
10
10
func wordSquares( _ words: [ String ] ) -> [ [ String ] ] {
11
- var paths = [ [ String] ] ( )
12
-
13
- guard words. count > 0 else {
14
- return paths
11
+ guard let first = words. first else {
12
+ return [ [ String] ] ( )
15
13
}
16
14
17
- var prefixWords = initPrefix ( words) , path = [ String] ( )
15
+ let prefixesToWords = buildMaps ( words) , rowNum = first. count
16
+ var paths = [ [ String] ] ( ) , path = [ String] ( )
18
17
19
- dfs ( & paths, & path, prefixWords , 0 , words [ 0 ] . count )
18
+ dfs ( & paths, path, prefixesToWords , rowNum , 0 )
20
19
21
20
return paths
22
21
}
23
22
24
- fileprivate func dfs( _ paths: inout [ [ String ] ] , _ path: inout [ String ] , _ prefixWords : [ String : [ String ] ] , _ row : Int , _ len : Int ) {
25
- if row == len {
26
- paths. append ( Array ( path) )
23
+ private func dfs( _ paths: inout [ [ String ] ] , _ path: [ String ] , _ prefixesToWords : [ String : [ String ] ] , _ rowNum : Int , _ currentRow : Int ) {
24
+ if currentRow == rowNum {
25
+ paths. append ( path)
27
26
return
28
27
}
29
28
30
- var pre = " "
31
- for i in 0 ..< row {
32
- pre = " \( pre ) \( Array ( path [ i] ) [ row ] ) "
29
+ var prefix = " "
30
+ for i in 0 ..< currentRow {
31
+ prefix . append ( Array ( path [ i] ) [ currentRow ] )
33
32
}
34
33
35
- guard let words = prefixWords [ pre ] else {
34
+ guard let words = prefixesToWords [ prefix ] else {
36
35
return
37
36
}
38
37
39
38
for word in words {
40
- path. append ( word)
41
- dfs ( & paths, & path, prefixWords, row + 1 , len)
42
- path. removeLast ( )
39
+ dfs ( & paths, path + [ word] , prefixesToWords, rowNum, currentRow + 1 )
43
40
}
44
41
}
45
42
46
- fileprivate func initPrefix ( _ words: [ String ] ) -> [ String : [ String ] ] {
47
- var prefix = [ String: [ String] ] ( )
43
+ private func buildMaps ( _ words: [ String ] ) -> [ String : [ String ] ] {
44
+ var res = [ String: [ String] ] ( )
48
45
49
46
for word in words {
50
- prefix [ " " ] = prefix [ " " , default: [ ] ] + [ word]
51
-
52
- var pre = " "
53
- for c in word {
54
- pre = " \( pre) \( c) "
55
-
56
- prefix [ pre] = prefix [ pre, default: [ ] ] + [ word]
47
+ for prefix in prefixes ( word) {
48
+ res [ prefix, default: [ ] ] . append ( word)
57
49
}
58
50
}
59
51
60
- return prefix
52
+ return res
53
+ }
54
+
55
+ private func prefixes( _ word: String ) -> [ String ] {
56
+ var res = [ " " ] , prefix = " "
57
+
58
+ for char in word {
59
+ prefix. append ( char)
60
+ res. append ( prefix)
61
+ }
62
+
63
+ return res
61
64
}
62
65
}
0 commit comments