9
9
10
10
class AlienDictionary {
11
11
func alienOrder( _ words: [ String ] ) -> String {
12
- var res = " " , queueChars = [ Character] ( )
13
- var ( indegrees, charToChars) = initGraph ( words)
12
+ var ( inDegrees, toChars) = buildGraph ( words)
14
13
15
- indegrees. keys. filter { indegrees [ $0] == 0 } . forEach { queueChars. append ( $0) }
14
+ var queue = inDegrees. keys. filter { inDegrees [ $0] == 0 }
15
+ var res = " "
16
16
17
- while !queueChars. isEmpty {
18
- let char = queueChars. removeFirst ( )
19
- res. append ( char)
17
+ while !queue. isEmpty {
18
+ let char = queue. removeFirst ( )
20
19
21
- guard let toChars = charToChars [ char] else {
22
- fatalError ( " Init Graph Error " )
23
- }
20
+ res. append ( char)
24
21
25
- for toChar in toChars {
26
- guard let indegree = indegrees [ toChar] else {
27
- fatalError ( " Init Graph Error " )
28
- }
22
+ for nextChar in toChars [ char] ! {
23
+ inDegrees [ nextChar] ! -= 1
29
24
30
- indegrees [ toChar] = indegree - 1
31
- if indegree == 1 {
32
- queueChars. append ( toChar)
25
+ if inDegrees [ nextChar] == 0 {
26
+ queue. append ( nextChar)
33
27
}
34
28
}
35
29
}
36
30
37
- return res. count == indegrees . count ? res : " "
31
+ return res. count == inDegrees . count ? res : " "
38
32
}
39
33
40
- private func initGraph( _ words: [ String ] ) -> ( [ Character : Int ] , [ Character : [ Character ] ] ) {
41
- var indegrees = [ Character: Int] ( ) , charToChars = [ Character: [ Character] ] ( )
34
+ private func buildGraph( _ words: [ String ] ) -> ( [ Character : Int ] , [ Character : [ Character ] ] ) {
35
+ // init inDegrees and toChars
36
+ var inDegrees = [ Character: Int] ( ) , toChars = [ Character: [ Character] ] ( )
42
37
43
- // init indegress and charToChars
44
38
words. forEach { word in
45
39
word. forEach { char in
46
- indegrees [ char] = 0
47
- charToChars [ char] = [ Character] ( )
48
- }
40
+ inDegrees [ char] = 0
41
+ toChars [ char] = [ Character] ( )
42
+ }
49
43
}
50
44
51
- // refactor indegress and charToChars based on words
45
+ // update based on orders
52
46
for i in 0 ..< words. count - 1 {
53
- let currentWord = Array ( words [ i] ) , nextWord = Array ( words [ i + 1 ] )
54
- var j = 0
55
-
56
- while j < currentWord. count && j < nextWord. count {
57
- let currentChar = currentWord [ j] , nextChar = nextWord [ j]
58
-
59
- if nextChar == currentChar {
60
- j += 1
47
+ let left = Array ( words [ i] ) , right = Array ( words [ i + 1 ] )
48
+
49
+ for j in 0 ..< min ( left. count, right. count) {
50
+ if left [ j] == right [ j] {
51
+
52
+ // invalid use case
53
+ if j + 1 == right. count && right. count < left. count {
54
+ return ( [ Character: Int] ( ) , [ Character: [ Character] ] ( ) )
55
+ }
56
+
61
57
continue
62
58
}
63
- if let toChars = charToChars [ currentChar] , toChars. contains ( nextChar) {
59
+
60
+ if toChars [ left [ j] ] !. contains ( right [ j] ) {
64
61
break
65
62
}
66
-
67
- indegrees [ nextChar , default : 0 ] += 1
68
- charToChars [ currentChar , default : [ Character ] ( ) ] . append ( nextChar )
63
+
64
+ inDegrees [ right [ j ] ] ! += 1
65
+ toChars [ left [ j ] ] ! . append ( right [ j ] )
69
66
break
67
+
70
68
}
71
-
72
69
}
73
-
74
- return ( indegrees , charToChars )
70
+
71
+ return ( inDegrees , toChars )
75
72
}
76
73
}
0 commit comments