1
+ /*
2
+ Author: King, wangjingui@outlook.com
3
+ Date: Dec 29, 2014
4
+ Problem: Word Ladder II
5
+ Difficulty: High
6
+ Source: https://oj.leetcode.com/problems/word-ladder-ii/
7
+ Notes:
8
+ Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
9
+ Only one letter can be changed at a time
10
+ Each intermediate word must exist in the dictionary
11
+ For example,
12
+ Given:
13
+ start = "hit"
14
+ end = "cog"
15
+ dict = ["hot","dot","dog","lot","log"]
16
+ Return
17
+ [
18
+ ["hit","hot","dot","dog","cog"],
19
+ ["hit","hot","lot","log","cog"]
20
+ ]
21
+ Note:
22
+ All words have the same length.
23
+ All words contain only lowercase alphabetic characters.
24
+
25
+ Solution: BFS + DFS
26
+ */
27
+
28
+ public class Solution {
29
+ public List <List <String >>findLadders (String start ,String end ,Set <String >dict ) {
30
+ List <List <String >>res =new ArrayList <List <String >>();
31
+ if (start .compareTo (end ) ==0 )return res ;
32
+ Set <String >visited =new HashSet <String >();
33
+ Set <String >cur =new HashSet <String >();
34
+ HashMap <String ,ArrayList <String >>graph =new HashMap <String ,ArrayList <String >>();
35
+ graph .put (end ,new ArrayList <String >());
36
+ cur .add (start );
37
+ boolean found =false ;
38
+ while (cur .isEmpty () ==false &&found ==false ) {
39
+ Set <String >queue =new HashSet <String >();
40
+ for (Iterator <String >it =cur .iterator ();it .hasNext ();) {
41
+ visited .add (it .next ());
42
+ }
43
+ for (Iterator <String >it =cur .iterator ();it .hasNext ();) {
44
+ String str =it .next ();
45
+ char []word =str .toCharArray ();
46
+ for (int j =0 ;j <word .length ; ++j ) {
47
+ char before =word [j ];
48
+ for (char ch ='a' ;ch <='z' ; ++ch ) {
49
+ if (ch ==before )continue ;
50
+ word [j ] =ch ;
51
+ String temp =new String (word );
52
+ if (dict .contains (temp ) ==false )continue ;
53
+ if (found ==true &&end .compareTo (temp ) !=0 )continue ;
54
+ if (end .compareTo (temp ) ==0 ) {
55
+ found =true ;
56
+ (graph .get (end )).add (str );
57
+ continue ;
58
+ }
59
+ if (visited .contains (temp ) ==false ) {
60
+ queue .add (temp );
61
+ if (graph .containsKey (temp ) ==false ) {
62
+ ArrayList <String >l =new ArrayList <String >();
63
+ l .add (str );
64
+ graph .put (temp ,l );
65
+ }else {
66
+ (graph .get (temp )).add (str );
67
+ }
68
+ }
69
+ }
70
+ word [j ] =before ;
71
+ }
72
+ }
73
+ cur =queue ;
74
+ }
75
+ if (found ==true ) {
76
+ ArrayList <String >path =new ArrayList <String >();
77
+ trace (res ,graph ,path ,start ,end );
78
+ }
79
+ return res ;
80
+ }
81
+ public void trace (List <List <String >>res ,
82
+ HashMap <String ,ArrayList <String >>graph ,
83
+ ArrayList <String >path ,
84
+ String start ,String now ) {
85
+ path .add (now );
86
+ if (now .compareTo (start ) ==0 ) {
87
+ ArrayList <String >ans =new ArrayList <String >(path );
88
+ Collections .reverse (ans );
89
+ res .add (ans );
90
+ path .remove (path .size ()-1 );
91
+ return ;
92
+ }
93
+ ArrayList <String >cur =graph .get (now );
94
+ for (int i =0 ;i <cur .size (); ++i ) {
95
+ trace (res ,graph ,path ,start ,cur .get (i ));
96
+ }
97
+ path .remove (path .size ()-1 );
98
+ }
99
+ }