public string SearchLevel(BFSNode sourceNode, BFSNode targetNode, ISet <String> validWords)
        {
            Queue <PathNode> toBeVisited = sourceNode.ToBeVisitedNodes;

            while (toBeVisited.Count > 0)
            {
                PathNode node = toBeVisited.Dequeue();

                // Is it visited bottom up?
                if (targetNode.VisitedNodes.ContainsKey(node.Word))
                {
                    //Yes.. return the common word;
                    return(node.Word);
                }

                // Has it already been visited as a part of the current queue?
                IList <string> validNextWords = WordLadderHelper.GetValidLinkedWords(node.Word, validWords);

                foreach (string validWord in validNextWords)
                {
                    if (!sourceNode.VisitedNodes.ContainsKey(validWord))
                    {
                        PathNode pn = new PathNode(validWord, node);
                        sourceNode.VisitedNodes.Add(validWord, pn);
                        sourceNode.ToBeVisitedNodes.Enqueue(pn);
                    }
                }
            }
            return(null);
        }
        public IList <string> GetWordLadderPath(string source, string target, ISet <string> validWords)
        {
            BFSNode sourceNode = new BFSNode(source);
            BFSNode targetNode = new BFSNode(target);


            while (!sourceNode.IsComplete && !targetNode.IsComplete)
            {
                string link = SearchLevel(sourceNode, targetNode, validWords);
                if (link != null)

                {
                    return(MergePaths(sourceNode, targetNode, link));
                }

                link = SearchLevel(targetNode, sourceNode, validWords);
                if (link != null)
                {
                    var res = MergePaths(sourceNode, targetNode, link);
                    return(MergePaths(sourceNode, targetNode, link));
                }
            }

            return(null);
        }
        private IList <string> MergePaths(BFSNode sourceNode, BFSNode destNode, string link)
        {
            PathNode       end1  = sourceNode.VisitedNodes[link];
            PathNode       end2  = destNode.VisitedNodes[link];
            IList <string> list1 = end1.Collapse(false);
            IList <string> list2 = end2.Collapse(true);

            list2.RemoveAt(0);

            for (int i = 0; i < list2.Count; i++)
            {
                list1.Add(list2[i]);
            }
            //list2 = null;
            return(list1);
        }
        public IList <IList <string> > GetWordLadderPath2(string source, string target, ISet <string> validWords)
        {
            BFSNode sourceNode = new BFSNode(source);
            BFSNode targetNode = new BFSNode(target);
            IList <IList <string> > allShortestpaths = new List <IList <string> >();
            HashSet <string>        uniqueLinkWords  = new HashSet <string>();

            //int shortestPathLength = 0;
            while (!sourceNode.IsComplete && !targetNode.IsComplete)
            {
                ISet <string> links = SearchLevel2(sourceNode, targetNode, validWords);
                foreach (string link in links)
                {
                    if (!uniqueLinkWords.Contains(link))
                    {
                        uniqueLinkWords.Add(link);
                        var res = MergePaths(sourceNode, targetNode, link);
                        allShortestpaths.Add(res);
                    }
                }

                links = SearchLevel2(targetNode, sourceNode, validWords);
                foreach (string link in links)
                {
                    if (!uniqueLinkWords.Contains(link))
                    {
                        uniqueLinkWords.Add(link);
                        var res = MergePaths(sourceNode, targetNode, link);
                        allShortestpaths.Add(res);
                    }
                }
            }

            int len = allShortestpaths.Select(x => x.Count).Min();

            return(allShortestpaths.Where(x => x.Count == len).ToList());
        }