-
Notifications
You must be signed in to change notification settings - Fork 0
/
18_10.cpp
124 lines (110 loc) · 3.46 KB
/
18_10.cpp
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
//
// 18_10.cpp
//
//
// Created by Pengyan Qin on 7/25/15.
//
//
// Given two words(start, end), and a dictionary, find the length of shortest transformation from
// start to end
#include <iostream>
#include <vector>
#include <string> //
#include <map> // for traces and array dict
#include <unordered_set> // for dictionary
using namespace std;
const int MAX = (1 << 30);
typedef vector<string> vs;
// time complexity: O(26*m), m is the word length
int word_ladder_length(string A[], int n, string start, string end){
if(start.size() != end.size())
return -1;
map<string, bool> mymap;
for(int i = 0; i < n; ++i){
mymap[A[i]] = true;
}
vs path[2];
int cur = 0;
int pre = 1;
path[cur].push_back(start);
int len = 0;
while(!path[cur].empty()){
len++;
for(int i = 0; i < path[cur].size(); ++i) // erase all ready considered words
mymap[path[cur][i]] = false;
cur = !cur;
pre = !pre;
path[cur].clear();
for(int i = 0; i < path[pre].size(); ++i){
string word = path[pre][i];
for(int j = 0; j < word.size(); ++j){
for(int c = 'a'; c <= 'z'; ++c){
string tmp = word;
if(c != tmp[j]){
tmp[j] = c;
if(mymap[tmp]){
if(tmp == end){
len++;
return len;
}
else
path[cur].push_back(tmp);
}
}
}
}
}
}
return MAX;
}
// time complexity: O(26*m), m is the word length
// the dictionary should be unordered_set, then do not need unordered_map
// unordered_set have find(), erase(), insert() function, while array do not have
int word_ladder_length1(unordered_set<string> A, string start, string end){
if(start.size() != end.size())
return -1;
A.insert(start);
A.insert(end);
vs path[2];
int cur = 0;
int pre = 1;
path[cur].push_back(start);
int len = 0;
while(!path[cur].empty()){
len++;
for(int i = 0; i < path[cur].size(); ++i) // erase all ready considered words
A.erase(path[cur][i]);
cur = !cur;
pre = !pre;
path[cur].clear();
for(int i = 0; i < path[pre].size(); ++i){
string word = path[pre][i];
for(int j = 0; j < word.size(); ++j){
for(int c = 'a'; c <= 'z'; ++c){
string tmp = word;
if(c != tmp[j]){
tmp[j] = c;
if(A.find(tmp) != A.end()){
if(tmp == end){
len++;
return len;
}
else
path[cur].push_back(tmp);
}
}
}
}
}
}
return MAX;
}
int main(){
string A[] = {"hot", "dot", "dog", "lot", "log", "hit", "cog"};
unordered_set<string> A1 = { "hot", "dot", "dog", "lot", "log", "hit", "cog" };
int n = 7;
string start = "hit";
string end = "cog";
cout << word_ladder_length(A, n, start, end) << endl;
cout << word_ladder_length1(A1, start, end) << endl;
}