public IList <IList <string> > FindLadders(string beginWord, string endWord, IList <string> wordList) { if (!wordList.Contains(endWord)) { return((IList <IList <string> >) new List <IList <string> >()); } var infoTree = InfoGraph.GetTreeFrom(beginWord, wordList, endWord, out var endWordIndex, out bool impossibleGetEndWordIndex, out int maxPathValue); if (impossibleGetEndWordIndex) { return((IList <IList <string> >) new List <IList <string> >()); } return(infoTree.getAllWordPathFromTo(0 /*beginWordIndex*/, endWordIndex, maxPathValue)); }
public static InfoGraph GetTreeFrom(string beginWord, IList <string> wordList, string endWord, out int endWordIndex, out bool impossibleGetEndWordIndex, out int maxPathValue) { InfoGraph tree = new InfoGraph(beginWord, wordList); endWordIndex = 0; for (; endWordIndex < tree.Infos.Length; endWordIndex++) { if (tree.Infos[endWordIndex] == endWord) { break; } } if (endWordIndex == tree.Infos.Length) { impossibleGetEndWordIndex = true; maxPathValue = int.MaxValue; return(null); } CreateNearByLetterRelations(tree); InfoGraph result = GetMinimumPathGraph(tree, 0, endWordIndex, out impossibleGetEndWordIndex, out maxPathValue); return(result); }
private static void CreateNearByLetterRelations(InfoGraph infoTree) { for (int i = 0; i < infoTree.Infos.Length - 1; i++) { for (int j = i + 1; j < infoTree.Infos.Length; j++) { if (AreNearByLetter(infoTree.Infos[i], infoTree.Infos[j])) { if (infoTree.relations[i] == null) { infoTree.relations[i] = new LinkedList <int>(); } infoTree.relations[i].AddLast(j); if (infoTree.relations[j] == null) { infoTree.relations[j] = new LinkedList <int>(); } infoTree.relations[j].AddLast(i); } } } }
private static InfoGraph GetMinimumPathGraph(InfoGraph graph, int beginWordIndex, int endWordIndex, out bool impossibleGetEndWordIndex, out int maxPathValue) { impossibleGetEndWordIndex = true; maxPathValue = int.MaxValue; MyHeap2 <int, int[]> heap = new MyHeap2 <int, int[]>(graph.Infos.Length); InfoGraph graphResult = new InfoGraph(graph.Infos); bool[] selected = new bool[graph.Infos.Length]; int[] pathValues = new int[graph.Infos.Length]; LinkedList <int[]> queue = new LinkedList <int[]>(); selected[beginWordIndex] = true; queue.AddLast(new int[] { beginWordIndex, -1 }); bool endWordSelected = false; while (queue.Count != 0) { var first = queue.First; queue.RemoveFirst(); int index = first.Value[0]; pathValues[index] = 1 + first.Value[1]; if (index == endWordIndex) { endWordSelected = true; impossibleGetEndWordIndex = false; maxPathValue = pathValues[index]; } if (graph.relations[index] != null) { if (graphResult.relations[index] == null) { graphResult.relations[index] = new LinkedList <int>(); } foreach (var item in graph.relations[index]) { if (endWordSelected) { if (item != endWordIndex) { continue; } else { if (pathValues[index] == pathValues[endWordIndex]) { queue.Clear(); break; } } } if (!selected[item]) { selected[item] = true; queue.AddLast(new int[] { item, pathValues[index] }); } graphResult.relations[index].AddLast(item); } } } return(graphResult); }