1
+
2
+ using System ;
3
+ using System . Collections . Generic ;
4
+ using System . Linq ;
5
+ using System . Text ;
6
+ using System . Threading . Tasks ;
7
+
8
+ namespace _126WordLadderII_P1
9
+ {
10
+ /// <summary>
11
+ /// Leetcode 126: Word ladder II
12
+ /// code review on July 9, 2018
13
+ /// </summary>
14
+ class Program
15
+ {
16
+ static void Main ( string [ ] args )
17
+ {
18
+ string beginWord = "hit" ;
19
+ string endWord = "cog" ;
20
+ var words = new string [ 5 ] { "hot" , "dot" , "dog" , "lot" , "log" } ;
21
+ var wordList = new HashSet < string > ( words ) ;
22
+
23
+ var result = FindLadders ( beginWord , endWord , wordList ) ;
24
+ }
25
+
26
+ private static List < List < String > > Ladders = new List < List < string > > ( ) ;
27
+ private static List < String > Words = new List < string > ( ) ;
28
+
29
+ public static List < List < String > > FindLadders (
30
+ String beginWord ,
31
+ String endWord ,
32
+ ISet < String > wordList ) {
33
+
34
+ var ladders = new List < List < string > > ( ) ;
35
+
36
+ if ( beginWord . CompareTo ( endWord ) == 0 ) {
37
+ var words = new List < string > ( ) ;
38
+
39
+ words . Add ( beginWord ) ;
40
+ ladders . Add ( words ) ;
41
+ return ladders ;
42
+ }
43
+
44
+ var dict = new HashSet < string > ( ) ;
45
+
46
+ dict = new HashSet < string > ( wordList ) ;
47
+ dict . Add ( endWord ) ;
48
+
49
+ var dictionary = new Dictionary < String , int > ( ) ;
50
+ int dist = getLadderLengthAndDictionary ( beginWord , endWord , dict , dictionary ) ;
51
+
52
+ var keys = new List < string > ( dictionary . Keys ) ;
53
+ foreach ( string key in keys )
54
+ {
55
+ dictionary [ key ] = dist - 1 - dictionary [ key ] ;
56
+ }
57
+
58
+ var visited = new HashSet < string > ( ) ;
59
+
60
+ getLadders ( dist - 1 , beginWord , endWord , dict , visited , dictionary ) ;
61
+
62
+ return ladders ;
63
+ }
64
+
65
+ /// <summary>
66
+ ///
67
+ /// </summary>
68
+ /// <param name="beginWord"></param>
69
+ /// <param name="endWord"></param>
70
+ /// <param name="wordList"></param>
71
+ /// <param name="ladderDictionary"></param>
72
+ /// <returns></returns>
73
+ private static int getLadderLengthAndDictionary (
74
+ String beginWord ,
75
+ String endWord ,
76
+ ISet < String > wordList ,
77
+ Dictionary < String , int > ladderDictionary )
78
+ {
79
+ int length = 0 ;
80
+
81
+ var visited = new HashSet < string > ( ) ;
82
+
83
+ var queue = new Queue < string > ( ) ;
84
+ var queueDist = new Queue < int > ( ) ;
85
+
86
+ queue . Enqueue ( beginWord ) ;
87
+
88
+ queueDist . Enqueue ( 0 ) ;
89
+
90
+ visited . Add ( beginWord ) ;
91
+
92
+ while ( queue . Count > 0 ) {
93
+
94
+ var word = queue . Dequeue ( ) ;
95
+ int len = queueDist . Dequeue ( ) ;
96
+
97
+ ladderDictionary [ word ] = len ;
98
+
99
+ if ( word . CompareTo ( endWord ) == 0 ) {
100
+ length = len + 1 ;
101
+ break ;
102
+ }
103
+
104
+ // get all neighbors of w, and add them to the queue,
105
+ // if they have not been visited.
106
+ for ( int i = 0 ; i < word . Length ; ++ i ) {
107
+ for ( int iterate = 'a' ; iterate <= 'z' ; ++ iterate ) {
108
+ var characters = word . ToCharArray ( ) ;
109
+
110
+ if ( iterate != characters [ i ] ) {
111
+ characters [ i ] = ( char ) iterate ; // don't forget type conversion.
112
+ var current = new String ( characters ) ;
113
+
114
+ if ( wordList . Contains ( current ) && ! visited . Contains ( current ) ) {
115
+ queue . Enqueue ( current ) ;
116
+
117
+ queueDist . Enqueue ( len + 1 ) ;
118
+
119
+ visited . Add ( current ) ;
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ return length ;
127
+ }
128
+
129
+ /// <summary>
130
+ /// code review on July 9, 2018
131
+ /// </summary>
132
+ /// <param name="dist"></param>
133
+ /// <param name="word"></param>
134
+ /// <param name="endWord"></param>
135
+ /// <param name="dict"></param>
136
+ /// <param name="visited"></param>
137
+ /// <param name="ladderDictionary"></param>
138
+ private static void getLadders (
139
+ int dist ,
140
+ String word ,
141
+ String endWord ,
142
+ ISet < String > dict ,
143
+ ISet < String > visited ,
144
+ Dictionary < String , int > ladderDictionary )
145
+ {
146
+ visited . Add ( word ) ;
147
+ Words . Add ( word ) ;
148
+
149
+ if ( word . CompareTo ( endWord ) == 0 ) {
150
+ var list = new List < string > ( ) ;
151
+
152
+ list . AddRange ( Words ) ;
153
+ Ladders . Add ( list ) ;
154
+ }
155
+ else if ( dist == 0 || ladderDictionary [ word ] > dist ) {
156
+ // do nothing.
157
+ }
158
+ else
159
+ {
160
+ var characters = word . ToCharArray ( ) ;
161
+
162
+ for ( int i = 0 ; i < word . Length ; ++ i ) {
163
+ var current = characters [ i ] ;
164
+ var currentChar = word [ i ] ;
165
+
166
+ for ( int iterate = 'a' ; iterate <= 'z' ; ++ iterate ) {
167
+ if ( iterate != currentChar )
168
+ {
169
+ characters [ i ] = ( char ) iterate ;
170
+ var currentWord = new String ( characters ) ;
171
+
172
+ if ( dict . Contains ( currentWord ) && ! visited . Contains ( currentWord ) ) {
173
+ getLadders ( dist - 1 , currentWord , endWord , dict , visited , ladderDictionary ) ;
174
+ }
175
+ }
176
+ }
177
+
178
+ characters [ i ] = current ; // restore.
179
+ }
180
+ }
181
+
182
+ visited . Remove ( word ) ;
183
+ Words . RemoveAt ( Words . Count - 1 ) ;
184
+ }
185
+ }
186
+ }
187
+
0 commit comments