-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0126.Word Ladder II.swift
132 lines (105 loc) · 4.06 KB
/
0126.Word Ladder 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
class Solution {
func findLadders(_ beginWord: String, _ endWord: String, _ wordList: [String]) -> [[String]] {
// firstAttempt(beginWord, endWord, wordList)
var result = [[String]]()
var dict = Set<String>(wordList)
if !dict.contains(endWord) {
return result
}
var queue: [[String]] = [[beginWord]]
var found = false
var tempSeen = Set<String>()
var visited = Set<String>()
while queue.isEmpty == false && found == false {
let temp = queue
queue.removeAll()
visited.formUnion(tempSeen)
tempSeen.removeAll()
for path in temp {
let lastWord = Array(path.last!)
if path.last! == endWord {
found = true
result.append(path)
}
for i in 0..<lastWord.endIndex {
for char in "abcdefghijklmnopqrstuvwxyz" {
let newWord = String(lastWord[0..<i] + [char] + lastWord[i+1..<lastWord.endIndex])
if dict.contains(newWord) && visited.contains(newWord) == false {
tempSeen.insert(newWord)
queue.append(path+[newWord])
}
}
}
}
}
return result
}
private func firstAttempt(_ beginWord: String, _ endWord: String, _ wordList: [String]) -> [[String]] {
var result = [[String]]()
var dict = Set<String>(wordList)
var map = [String:[String]]()
if !dict.contains(endWord) {
return result
}
var startSet = Set<String>()
startSet.insert(beginWord)
var endSet = Set<String>()
endSet.insert(endWord)
bfs(startSet, endSet, dict, &map, false)
var list = [String]()
list.append(beginWord)
dfs(&result, &list, beginWord, endWord, &map)
return result
}
private func bfs(_ startSet: Set<String>, _ endSet: Set<String>, _ dict: Set<String>, _ map: inout [String:[String]], _ reversed: Bool) {
guard startSet.count != 0 else {
return
}
if startSet.count > endSet.count {
bfs(endSet, startSet, dict, &map, !reversed)
return
}
var finished = false
var temp = Set<String>();
var dict = dict.subtracting(startSet)
for s in startSet {
var chars = Array(s)
for i in 0..<chars.count {
let orig = chars[i]
for ch in "abcdefghijklmnopqrstvuwxyz" {
chars[i] = ch
let word = String(chars)
// print(word)
if dict.contains(word) {
if endSet.contains(word) {
finished = true
} else {
temp.insert(word)
}
let key = reversed ? word : s
let val = reversed ? s : word
map[key, default: [String]()].append(val)
}
}
chars[i] = orig
}
}
if !finished {
bfs(temp, endSet, dict, &map, reversed)
}
}
private func dfs(_ result: inout [[String]], _ list: inout [String], _ beginWord: String, _ endWord: String, _ map: inout [String:[String]]) {
if beginWord == endWord {
result.append(list)
return
}
if map[beginWord] == nil {
return
}
for word in map[beginWord]! {
list.append(word)
dfs(&result, &list, word, endWord, &map)
list.removeLast()
}
}
}