1
-
2
-
3
1
import java .util .ArrayList ;
2
+ import java .util .HashMap ;
4
3
import java .util .HashSet ;
5
- import java .util .LinkedList ;
6
- import java .util .Queue ;
4
+ import java .util .Map ;
7
5
8
6
/**
9
7
* Given two words (start and end), and a dictionary, find all shortest
23
21
*/
24
22
25
23
public class WordLadderII {
24
+ private void GeneratePath (Map <String , ArrayList <String >> prevMap ,
25
+ ArrayList <String > path , String word ,
26
+ ArrayList <ArrayList <String >> ret ) {
27
+ if (prevMap .get (word ).size () == 0 ) {
28
+ path .add (0 , word );
29
+ ArrayList <String > curPath = new ArrayList <String >(path );
30
+ ret .add (curPath );
31
+ path .remove (0 );
32
+ return ;
33
+ }
34
+
35
+ path .add (0 , word );
36
+ for (String pt : prevMap .get (word )) {
37
+ GeneratePath (prevMap , path , pt , ret );
38
+ }
39
+ path .remove (0 );
40
+ }
41
+
26
42
public ArrayList <ArrayList <String >> findLadders (String start , String end ,
27
43
HashSet <String > dict ) {
28
44
ArrayList <ArrayList <String >> ret = new ArrayList <ArrayList <String >>();
29
- int currentLevel = 1 , nextLevel = 0 ;
30
- boolean found = false ;
31
- HashSet <String > visited = new HashSet <String >();
45
+ Map <String , ArrayList <String >> prevMap = new HashMap <String , ArrayList <String >>();
46
+ dict .add (start );
47
+ dict .add (end );
48
+ for (String d : dict ) {
49
+ prevMap .put (d , new ArrayList <String >());
50
+ }
51
+ ArrayList <HashSet <String >> candidates = new ArrayList <HashSet <String >>();
52
+ candidates .add (new HashSet <String >());
53
+ candidates .add (new HashSet <String >());
54
+ int current = 0 ;
55
+ int previous = 1 ;
56
+ candidates .get (current ).add (start );
57
+ while (true ) {
58
+ current = current == 0 ? 1 : 0 ;
59
+ previous = previous == 0 ? 1 : 0 ;
60
+ for (String d : candidates .get (previous )) {
61
+ dict .remove (d );
62
+ }
63
+ candidates .get (current ).clear ();
64
+ for (String wd : candidates .get (previous )) {
65
+ for (int pos = 0 ; pos < wd .length (); ++pos ) {
66
+ StringBuffer word = new StringBuffer (wd );
67
+ for (int i = 'a' ; i <= 'z' ; ++i ) {
68
+ if (wd .charAt (pos ) == i ) {
69
+ continue ;
70
+ }
32
71
33
- Queue <String > q = new LinkedList <String >();
34
- q .add (start );
35
- Queue <ArrayList <String >> sequences = new LinkedList <ArrayList <String >>();
36
- ArrayList <String > l = new ArrayList <String >();
37
- l .add (start );
38
- sequences .add (l );
72
+ word .setCharAt (pos , (char ) i );
39
73
40
- while (!q .isEmpty ()) {
41
- String st = q .remove ();
42
- ArrayList <String > tmp = sequences .remove ();
43
- currentLevel --;
44
- if (st .equals (end )) {
45
- ret .add (tmp );
46
- found = true ;
47
- } else {
48
- if (!found ) {
49
- for (int i = 0 ; i < st .length (); i ++) {
50
- StringBuffer sb = new StringBuffer (st );
51
- for (int j = 0 ; j < 26 ; j ++) {
52
- sb .setCharAt (i , (char ) ('a' + j ));
53
- String next = sb .toString ();
54
- boolean in = false ;
55
- for (int g = 0 ; g < tmp .size (); g ++)
56
- if (tmp .get (g ).equals (next )) {
57
- in = true ;
58
- break ;
59
- }
60
- if (dict .contains (next ) && !in ) {
61
- q .add (next );
62
- visited .add (next );
63
- nextLevel ++;
64
- ArrayList <String > nexttmp = new ArrayList <String >(
65
- tmp );
66
- nexttmp .add (next );
67
- sequences .add (nexttmp );
68
- }
74
+ if (dict .contains (word .toString ())) {
75
+ prevMap .get (word .toString ()).add (wd );
76
+ candidates .get (current ).add (word .toString ());
69
77
}
70
78
}
71
79
}
72
80
}
73
- if (currentLevel == 0 ) {
74
- if (found )
75
- break ;
76
- else {
77
- currentLevel = nextLevel ;
78
- nextLevel = 0 ;
79
- }
81
+
82
+ if (candidates .get (current ).size () == 0 ) {
83
+ return ret ;
84
+ }
85
+ if (candidates .get (current ).contains (end )) {
86
+ break ;
80
87
}
81
88
}
82
89
90
+ ArrayList <String > path = new ArrayList <String >();
91
+ GeneratePath (prevMap , path , end , ret );
92
+
83
93
return ret ;
84
94
}
85
95
}
0 commit comments