# Word Ladder – Set 2 ( Bi-directional BFS )

Given a dictionary, and two words start and target (both of the same length). Find length of the smallest chain from start to target if it exists, such that adjacent words in the chain only differ by one character and each word in the chain is a valid word i.e., it exists in the dictionary. It may be assumed that the target word exists in the dictionary and the lengths of all the dictionary words are equal.
Examples:

Input: Dictionary = {POON, PLEE, SAME, POIE, PLEA, PLIE, POIN}
start = “TOON”
target = “PLEA”
Output:
TOON -> POON –> POIN –> POIE –> PLIE –> PLEE –> PLEA

Approach: This problem can be solved using the standard BFS approach as discussed here but its performance can be improved by using bi-directional BFS.
Bi-directional BFS doesn’t reduce the time complexity of the solution but it definitely optimizes the performance in many cases. This approach can also be used in many other shortest pathfinding problems where we have sufficient information about the source and the target node. The basic idea involved in bi-directional BFS is to start the search from both the ends of the path.
Therefore, two queues and two visited arrays are needed to be maintained to track both the paths. So, whenever a node (say A) is present in the source queue, encounters a node (say B) which is present in the target queue, then we can calculate the answer by adding the distance of A from source and the distance of B from target minus 1 (one node is common). This way we can calculate the answer in half the time as compared to the standard BFS approach. This method is also known as the meet-in-the-middle BFS approach.
Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach` `#include ` `using` `namespace` `std;`   `// Structure for queue` `struct` `node {` `    ``string word;` `    ``int` `len;` `};`   `// Function that returns true if a and b` `// differ in only a single character` `bool` `isAdj(string a, string b)` `{` `    ``int` `count = 0;` `    ``for` `(``int` `i = 0; i < a.length(); i++) {` `        ``if` `(a[i] != b[i])` `            ``count++;` `    ``}` `    ``if` `(count == 1)` `        ``return` `true``;` `    ``return` `false``;` `}`   `// Function to return the length of the shortest` `// chain from â€˜beginWordâ€™ to â€˜endWordâ€™` `int` `ladderLength(string beginWord, string endWord,` `                 ``vector& wordList)` `{`   `    ``/* q1 is used to traverse the graph from beginWord ` `        ``and q2 is used to traverse the graph from endWord.` `        ``vis1 and vis2 are used to keep track of the ` `        ``visited states from respective directions */` `    ``queue q1;` `    ``queue q2;` `    ``unordered_map vis1;` `    ``unordered_map vis2;`   `    ``node start = { beginWord, 1 };` `    ``node end = { endWord, 1 };`   `    ``vis1[beginWord] = 1;` `    ``q1.push(start);` `    ``vis2[endWord] = 1;` `    ``q2.push(end);`   `    ``while` `(!q1.empty() && !q2.empty()) {`   `        ``// Fetch the current node` `        ``// from the source queue` `        ``node curr1 = q1.front();` `        ``q1.pop();`   `        ``// Fetch the current node from` `        ``// the destination queue` `        ``node curr2 = q2.front();` `        ``q2.pop();`   `        ``// Check all the neighbors of curr1` `        ``for` `(``auto` `it = wordList.begin(); it != wordList.end(); it++) {`   `            ``// If any one of them is adjacent to curr1` `            ``// and is not present in vis1` `            ``// then push it in the queue` `            ``if` `(isAdj(curr1.word, *it) && vis1.count(*it) == ``false``) {`   `                ``node temp = { *it, curr1.len + 1 };` `                ``q1.push(temp);` `                ``vis1[*it] = curr1.len + 1;`   `                ``// If temp is the destination node` `                ``// then return the answer` `                ``if` `(temp.word == endWord) {` `                    ``return` `temp.len;` `                ``}`   `                ``// If temp is present in vis2 i.e. distance from` `                ``// temp and the destination is already calculated` `                ``if` `(vis2.count(temp.word)) {` `                    ``return` `temp.len + vis2[temp.word] - 1;` `                ``}` `            ``}` `        ``}`   `        ``// Check all the neighbors of curr2` `        ``for` `(``auto` `it = wordList.begin(); it != wordList.end(); it++) {`   `            ``// If any one of them is adjacent to curr2` `            ``// and is not present in vis1 then push it in the queue.` `            ``if` `(isAdj(curr2.word, *it) && vis2.count(*it) == ``false``) {`   `                ``node temp = { *it, curr2.len + 1 };` `                ``q2.push(temp);` `                ``vis2[*it] = curr2.len + 1;`   `                ``// If temp is the destination node` `                ``// then return the answer` `                ``if` `(temp.word == beginWord) {` `                    ``return` `temp.len;` `                ``}`   `                ``// If temp is present in vis1 i.e. distance from` `                ``// temp and the source is already calculated` `                ``if` `(vis1.count(temp.word)) {` `                    ``return` `temp.len + vis1[temp.word] - 1;` `                ``}` `            ``}` `        ``}` `    ``}` `    ``return` `0;` `}`   `// Driver code` `int` `main()` `{`   `    ``vector wordList;` `    ``wordList.push_back(``"poon"``);` `    ``wordList.push_back(``"plee"``);` `    ``wordList.push_back(``"same"``);` `    ``wordList.push_back(``"poie"``);` `    ``wordList.push_back(``"plie"``);` `    ``wordList.push_back(``"poin"``);` `    ``wordList.push_back(``"plea"``);`   `    ``string start = ``"toon"``;` `    ``string target = ``"plea"``;`   `    ``cout << ladderLength(start, target, wordList);`   `    ``return` `0;` `}`

## Java

 `import` `java.util.*;` `public` `class` `GFG` `{` `public` `static` `class` `node` `{` `    ``String word;` `    ``int` `len;` `    ``public` `node(String word, ``int` `len)` `    ``{` `        ``this``.word = word;` `        ``this``.len = len;` `    ``}` `}`   `public` `static` `boolean` `isAdj(String a, String b) ` `{ ` `    ``int` `count = ``0``; ` `    ``for` `(``int` `i = ``0``; i < a.length(); i++) ` `    ``{ ` `        ``if` `(a.charAt(i) != b.charAt(i)) ` `            ``count++; ` `    ``} ` `    ``if` `(count == ``1``) ` `        ``return` `true``; ` `    ``return` `false``; ` `} `   `// Function to return the length of the shortest ` `// chain from 'beginWord' to 'endWord' ` `public` `static` `int` `ladderLength(String beginWord, String endWord, ` `                               ``ArrayList wordList) ` `{ `   `    ``/* q1 is used to traverse the graph from beginWord ` `        ``and q2 is used to traverse the graph from endWord. ` `        ``vis1 and vis2 are used to keep track of the ` `        ``visited states from respective directions */` `    ``Queue q1 = ``new` `LinkedList<>(); ` `    ``Queue q2 = ``new` `LinkedList<>(); ` `    ``HashMap vis1 = ``new` `HashMap<>(); ` `    ``HashMap vis2 = ``new` `HashMap<>(); `   `    ``node start = ``new` `node(beginWord, ``1``); ` `    ``node end = ``new` `node(endWord, ``1``); `   `    ``vis1.put(beginWord, ``1``); ` `    ``q1.add(start); ` `    ``vis2.put(endWord, ``1``); ` `    ``q2.add(end); `   `    ``while` `(q1.size() > ``0` `&& q2.size() > ``0``) ` `    ``{ `   `        ``// Fetch the current node ` `        ``// from the source queue ` `        ``node curr1 = q1.remove(); `   `        ``// Fetch the current node from ` `        ``// the destination queue ` `        ``node curr2 = q2.remove(); `   `        ``// Check all the neighbors of curr1 ` `        ``for` `(``int` `i = ``0``; i < wordList.size(); i++) ` `        ``{ `   `            ``// If any one of them is adjacent to curr1 ` `            ``// and is not present in vis1 ` `            ``// then push it in the queue ` `            ``if` `(isAdj(curr1.word,wordList.get(i)) && ` `                ``vis1.containsKey(wordList.get(i)) == ``false``)` `            ``{ `   `                ``node temp = ``new` `node(wordList.get(i),` `                                      ``curr1.len + ``1``); ` `                ``q1.add(temp); ` `                ``vis1.put(wordList.get(i), curr1.len + ``1``); `   `                ``// If temp is the destination node ` `                ``// then return the answer ` `                ``if` `(temp.word.equals(endWord)) ` `                ``{ ` `                    ``return` `temp.len; ` `                ``} `   `                ``// If temp is present in vis2 i.e. distance from ` `                ``// temp and the destination is already calculated ` `                ``if` `(vis2.containsKey(temp.word)) ` `                ``{ ` `                    ``return` `temp.len + vis2.get(temp.word) - ``1``; ` `                ``} ` `            ``} ` `        ``} `   `        ``// Check all the neighbors of curr2 ` `        ``for` `(``int` `i = ``0``; i < wordList.size(); i++) ` `        ``{ `   `            ``// If any one of them is adjacent to curr2 ` `            ``// and is not present in vis1 then push it in the queue. ` `            ``if` `(isAdj(curr2.word,wordList.get(i)) && ` `                ``vis2.containsKey(wordList.get(i)) == ``false``) ` `            ``{ `   `                ``node temp = ``new` `node(wordList.get(i), ` `                                     ``curr2.len + ``1` `); ` `                ``q2.add(temp); ` `                ``vis2.put(wordList.get(i), curr2.len + ``1``); `   `                ``// If temp is the destination node ` `                ``// then return the answer ` `                ``if` `(temp.word.equals(beginWord))` `                ``{ ` `                    ``return` `temp.len; ` `                ``} `   `                ``// If temp is present in vis1 i.e. distance from ` `                ``// temp and the source is already calculated ` `                ``if` `(vis1.containsKey(temp.word))` `                ``{ ` `                    ``return` `temp.len + vis1.get(temp.word) - ``1``; ` `                ``} ` `            ``} ` `        ``} ` `    ``} ` `    ``return` `0``; ` `} `   `// Driver code ` `public` `static` `void` `main(String args[]) ` `{ ` `    ``ArrayList wordList = ``new` `ArrayList<>(); ` `    ``wordList.add(``"poon"``); ` `    ``wordList.add(``"plee"``); ` `    ``wordList.add(``"same"``); ` `    ``wordList.add(``"poie"``); ` `    ``wordList.add(``"plie"``); ` `    ``wordList.add(``"poin"``); ` `    ``wordList.add(``"plea"``); `   `    ``String start = ``"toon"``; ` `    ``String target = ``"plea"``; `   `    ``System.out.println(ladderLength(start, target, wordList)); ` `} ` `}`   `// This code is contributed by Sambhav Jain`

## C#

 `// C# implementation of the approach    ` `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG` `{` `    `  `class` `node` `{` `    ``public` `String word;` `    ``public` `int` `len;` `    ``public` `node(String word, ``int` `len)` `    ``{` `        ``this``.word = word;` `        ``this``.len = len;` `    ``}` `}`   `public` `static` `bool` `isAdj(String a, String b) ` `{ ` `    ``int` `count = 0; ` `    ``for` `(``int` `i = 0; i < a.Length; i++) ` `    ``{ ` `        ``if` `(a[i] != b[i]) ` `            ``count++; ` `    ``} ` `    ``if` `(count == 1) ` `        ``return` `true``; ` `    ``return` `false``; ` `} `   `// Function to return the length of the shortest ` `// chain from 'beginWord' to 'endWord' ` `public` `static` `int` `ladderLength(String beginWord, String endWord, ` `                            ``List wordList) ` `{ `   `    ``/* q1 is used to traverse the graph from beginWord ` `        ``and q2 is used to traverse the graph from endWord. ` `        ``vis1 and vis2 are used to keep track of the ` `        ``visited states from respective directions */` `    ``Queue q1 = ``new` `Queue(); ` `    ``Queue q2 = ``new` `Queue(); ` `    ``Dictionary vis1 = ``new` `Dictionary(); ` `    ``Dictionary vis2 = ``new` `Dictionary(); `   `    ``node start = ``new` `node(beginWord, 1); ` `    ``node end = ``new` `node(endWord, 1); `   `    ``vis1.Add(beginWord, 1); ` `    ``q1.Enqueue(start); ` `    ``vis2.Add(endWord, 1); ` `    ``q2.Enqueue(end); `   `    ``while` `(q1.Count > 0 && q2.Count > 0) ` `    ``{ `   `        ``// Fetch the current node ` `        ``// from the source queue ` `        ``node curr1 = q1.Dequeue(); `   `        ``// Fetch the current node from ` `        ``// the destination queue ` `        ``node curr2 = q2.Dequeue(); `   `        ``// Check all the neighbors of curr1 ` `        ``for` `(``int` `i = 0; i < wordList.Count; i++) ` `        ``{ `   `            ``// If any one of them is adjacent to curr1 ` `            ``// and is not present in vis1 ` `            ``// then push it in the queue ` `            ``if` `(isAdj(curr1.word,wordList[i]) && ` `                ``vis1.ContainsKey(wordList[i]) == ``false``)` `            ``{ `   `                ``node temp = ``new` `node(wordList[i],` `                                    ``curr1.len + 1); ` `                ``q1.Enqueue(temp); ` `                ``vis1.Add(wordList[i], curr1.len + 1); `   `                ``// If temp is the destination node ` `                ``// then return the answer ` `                ``if` `(temp.word.Equals(endWord)) ` `                ``{ ` `                    ``return` `temp.len; ` `                ``} `   `                ``// If temp is present in vis2 i.e. distance from ` `                ``// temp and the destination is already calculated ` `                ``if` `(vis2.ContainsKey(temp.word)) ` `                ``{ ` `                    ``return` `temp.len + vis2[temp.word] - 1; ` `                ``} ` `            ``} ` `        ``} `   `        ``// Check all the neighbors of curr2 ` `        ``for` `(``int` `i = 0; i < wordList.Count; i++) ` `        ``{ `   `            ``// If any one of them is adjacent to curr2 ` `            ``// and is not present in vis1 then push it in the queue. ` `            ``if` `(isAdj(curr2.word,wordList[i]) && ` `                ``vis2.ContainsKey(wordList[i]) == ``false``) ` `            ``{ `   `                ``node temp = ``new` `node(wordList[i], ` `                                    ``curr2.len + 1 ); ` `                ``q2.Enqueue(temp); ` `                ``vis2.Add(wordList[i], curr2.len + 1); `   `                ``// If temp is the destination node ` `                ``// then return the answer ` `                ``if` `(temp.word.Equals(beginWord))` `                ``{ ` `                    ``return` `temp.len; ` `                ``} `   `                ``// If temp is present in vis1 i.e. distance from ` `                ``// temp and the source is already calculated ` `                ``if` `(vis1.ContainsKey(temp.word))` `                ``{ ` `                    ``return` `temp.len + vis1[temp.word] - 1; ` `                ``} ` `            ``} ` `        ``} ` `    ``} ` `    ``return` `0; ` `} `   `// Driver code ` `public` `static` `void` `Main(String []args) ` `{ ` `    ``List wordList = ``new` `List(); ` `    ``wordList.Add(``"poon"``); ` `    ``wordList.Add(``"plee"``); ` `    ``wordList.Add(``"same"``); ` `    ``wordList.Add(``"poie"``); ` `    ``wordList.Add(``"plie"``); ` `    ``wordList.Add(``"poin"``); ` `    ``wordList.Add(``"plea"``); `   `    ``String start = ``"toon"``; ` `    ``String target = ``"plea"``; `   `    ``Console.WriteLine(ladderLength(start, target, wordList)); ` `} ` `}`   `// This code is contributed by Rajput-Ji`

## Python3

 `# Python 3 implementation of the approach` `from` `collections ``import` `deque as dq`   `# class for queue` `class` `node :` `    ``def` `__init__(``self``, w, l):` `        ``self``.word``=``w` `        ``self``.``len``=``l`     `# Function that returns true if a and b` `# differ in only a single character` `def` `isAdj(a, b):` `    ``count ``=` `0` `    ``for` `i ``in` `range``(``len``(a)):` `        ``if` `(a[i] !``=` `b[i]):` `            ``count``+``=``1` `    `  `    ``if` `(count ``=``=` `1``):` `        ``return` `True` `    ``return` `False`     `# Function to return the length of the shortest` `# chain from â€˜beginWordâ€™ to â€˜endWordâ€™` `def` `ladderLength(beginWord, endWord, wordList):`   `    ``# q1 is used to traverse the graph from beginWord ` `    ``# and q2 is used to traverse the graph from endWord.` `    ``# vis1 and vis2 are used to keep track of the ` `    ``# visited states from respective directions` `    ``q1``=``dq([])` `    ``q2``=``dq([])` `    ``vis1``=``dict``()` `    ``vis2``=``dict``()`   `    ``start ``=` `node(beginWord, ``1``) ` `    ``end ``=` `node(endWord, ``1``)`   `    ``vis1[beginWord] ``=` `1` `    ``q1.append(start)` `    ``vis2[endWord] ``=` `1` `    ``q2.append(end)`   `    ``while` `(q1 ``and` `q2):`   `        ``# Fetch the current node` `        ``# from the source queue` `        ``curr1 ``=` `q1.popleft()`   `        ``# Fetch the current node from` `        ``# the destination queue` `        ``curr2 ``=` `q2.popleft()`   `        ``# Check all the neighbors of curr1` `        ``for` `it ``in` `wordList:`   `            ``# If any one of them is adjacent to curr1` `            ``# and is not present in vis1` `            ``# then push it in the queue` `            ``if` `(isAdj(curr1.word, it) ``and` `it ``not` `in` `vis1) :`   `                ``temp ``=` `node(it, curr1.``len` `+` `1``) ` `                ``q1.append(temp)` `                ``vis1[it] ``=` `curr1.``len` `+` `1`   `                ``# If temp is the destination node` `                ``# then return the answer` `                ``if` `(temp.word ``=``=` `endWord) :` `                    ``return` `temp.``len` `                `    `                ``# If temp is present in vis2 i.e. distance from` `                ``# temp and the destination is already calculated` `                ``if` `temp.word ``in` `vis2 :` `                    ``return` `temp.``len` `+` `vis2[temp.word] ``-` `1` `                `  `            `  `        `    `        ``# Check all the neighbors of curr2` `        ``for` `it ``in` `wordList:`   `            ``# If any one of them is adjacent to curr2` `            ``# and is not present in vis1 then push it in the queue.` `            ``if` `(isAdj(curr2.word, it) ``and` `it ``not` `in` `vis2) :`   `                ``temp ``=` `node(it, curr2.``len` `+` `1``) ` `                ``q2.append(temp)` `                ``vis2[it] ``=` `curr2.``len` `+` `1`   `                ``# If temp is the destination node` `                ``# then return the answer` `                ``if` `(temp.word ``=``=` `beginWord) :` `                    ``return` `temp.``len` `                `    `                ``# If temp is present in vis1 i.e. distance from` `                ``# temp and the source is already calculated` `                ``if` `temp.word ``in` `vis1:` `                    ``return` `temp.``len` `+` `vis1[temp.word] ``-` `1`            `    ``return` `0`     `# Driver code` `if` `__name__``=``=``'__main__'``:`   `    ``wordList``=``[]` `    ``wordList.append(``"poon"``)` `    ``wordList.append(``"plee"``)` `    ``wordList.append(``"same"``)` `    ``wordList.append(``"poie"``)` `    ``wordList.append(``"plie"``)` `    ``wordList.append(``"poin"``)` `    ``wordList.append(``"plea"``)`   `    ``start ``=` `"toon"` `    ``target ``=` `"plea"`   `    ``print``(ladderLength(start, target, wordList))`

## Javascript

 `class Node {` `  ``constructor(w, l) {` `    ``this``.word = w;` `    ``this``.len = l;` `  ``}` `}` `// Function that returns true if a and b` `// differ in only a single character`   `function` `isAdj(a, b) {` `  ``let count = 0;` `  ``for` `(let i = 0; i < a.length; i++) {` `    ``if` `(a[i] !== b[i]) {` `      ``count++;` `    ``}` `  ``}`   `  ``if` `(count === 1) {` `    ``return` `true``;` `  ``}` `  ``return` `false``;` `}` `//Function to return the length of the shortest` `//chain from â€˜beginWordâ€™ to â€˜endWord`   `function` `ladderLength(beginWord, endWord, wordList) {` `   ``// q1 is used to traverse the graph from beginWord ` `    ``// and q2 is used to traverse the graph from endWord.` `    ``//vis1 and vis2 are used to keep track of the ` `    ``//visited states from respective directions` `  ``const q1 = [];` `  ``const q2 = [];` `  ``const vis1 = {};` `  ``const vis2 = {};`   `  ``const start = ``new` `Node(beginWord, 1);` `  ``const end = ``new` `Node(endWord, 1);`   `  ``vis1[beginWord] = 1;` `  ``q1.push(start);` `  ``vis2[endWord] = 1;` `  ``q2.push(end);`   `  ``while` `(q1.length > 0 && q2.length > 0) {` `      ``// Fetch the current node` `        ``// from the source queue` `    ``const curr1 = q1.shift();` `    ``const curr2 = q2.shift();`   `    ``for` `(const it of wordList) {` `      ``if` `(isAdj(curr1.word, it) && !vis1[it]) {` `        ``const temp = ``new` `Node(it, curr1.len + 1);` `        ``q1.push(temp);` `        ``vis1[it] = curr1.len + 1;`   `        ``if` `(temp.word === endWord) {` `          ``return` `temp.len;` `        ``}`   `        ``if` `(temp.word ``in` `vis2) {` `          ``return` `temp.len + vis2[temp.word] - 1;` `        ``}` `      ``}` `    ``}`   `    ``for` `(const it of wordList) {` `      ``if` `(isAdj(curr2.word, it) && !vis2[it]) {` `        ``const temp = ``new` `Node(it, curr2.len + 1);` `        ``q2.push(temp);` `        ``vis2[it] = curr2.len + 1;`   `        ``if` `(temp.word === beginWord) {` `          ``return` `temp.len;` `        ``}`   `        ``if` `(temp.word ``in` `vis1) {` `          ``return` `temp.len + vis1[temp.word] - 1;` `        ``}` `      ``}` `    ``}` `  ``}`   `  ``return` `0;` `}`   `const wordList = [];` `wordList.push(``"poon"``);` `wordList.push(``"plee"``);` `wordList.push(``"same"``);` `wordList.push(``"poie"``);` `wordList.push(``"plie"``);` `wordList.push(``"poin"``);` `wordList.push(``"plea"``);`   `const start = ``"toon"``;` `const target = ``"plea"``;`   `console.log(ladderLength(start, target, wordList));`   `// This code is contributed by lokeshpotta20.`

Output

`7`

Time Complexity: O(N^2), where N is the length of the string.
Auxiliary Space: O(N).

Approach 2:

[Printing the sequence itself]

1. Perform BFS
2. Now in the BFS, instead of storing the string and level
3. We now store the sequence itself
4. We delete the words used in every level at the start of next level.
5. Hence we get the sequence

CODE:

## C++

 `// C++ implementation of the approach` `#include ` `using` `namespace` `std;`     `// Function to return the sequences itself` `vector> findSequences(string beginWord, string endWord, vector& wordList) {` `        `  `        ``vector> ans;` `        ``unordered_set vis(wordList.begin(), wordList.end());` `        ``vector UsedOnLvl;` `        `  `        ``queue> qu;` `        ``qu.push({beginWord});` `        ``int` `level = 0;` `        `  `        ``while``(!qu.empty()){` `            ``vector vec = qu.front();` `            ``qu.pop();` `            `  `            ``if``(vec.size() > level){` `                ``level++; ` `                ``//calc for next lvl is gonna happen` `                ``//lvl 0 1 2 3 4 5` `                `  `                ``//also del prev guys used` `                ``//or else infinite loop and not short len (duplication)` `                ``for``(``auto` `str : UsedOnLvl){` `                    ``vis.erase(str);` `                ``}` `                ``UsedOnLvl.clear(); ``// cleared ` `            ``}` `            `  `            `  `            ``string last = vec.back();` `            `  `            ``if``(last == endWord){` `                ``if``(ans.size() == 0){` `                    ``//1st time` `                    ``ans.push_back(vec);` `                ``}` `                ``//we have one or more` `                ``else` `if``(ans[0].size() == vec.size()){` `                    ``//same len then add it` `                    ``ans.push_back(vec);` `                ``}` `            ``}` `            `  `            ``for``(``int` `i=0; i wordList;` `    ``wordList.push_back(``"poon"``);` `    ``wordList.push_back(``"plee"``);` `    ``wordList.push_back(``"same"``);` `    ``wordList.push_back(``"poie"``);` `    ``wordList.push_back(``"plie"``);` `    ``wordList.push_back(``"poin"``);` `    ``wordList.push_back(``"plea"``);`   `    ``string start = ``"toon"``;` `    ``string target = ``"plea"``;`   `    ``vector> ans = findSequences(start, target, wordList);` `      ``for``(``auto` `a : ans){` `        ``for``(string s : a){` `            ``cout<

## Java

 `import` `java.util.*;`   `public` `class` `Main {`   `    ``// Function to return the sequences itself` `    ``static` `List> findSequences(String beginWord, String endWord, List wordList) {` `        ``List> ans = ``new` `ArrayList<>();` `        ``Set vis = ``new` `HashSet<>(wordList);` `        ``List UsedOnLvl = ``new` `ArrayList<>();`   `        ``Queue> qu = ``new` `LinkedList<>();` `        ``List temp = ``new` `ArrayList<>();` `        ``temp.add(beginWord);` `        ``qu.add(temp);` `        ``int` `level = ``0``;`   `        ``while` `(!qu.isEmpty()) {` `            ``List vec = qu.poll();`   `            ``if` `(vec.size() > level) {` `                ``level++;` `                ``//calc for next lvl is gonna happen` `                ``//lvl 0 1 2 3 4 5`   `                ``//also del prev guys used` `                ``//or else infinite loop and not short len (duplication)` `                ``for` `(String str : UsedOnLvl) {` `                    ``vis.remove(str);` `                ``}` `                ``UsedOnLvl.clear(); ``// cleared` `            ``}`   `            ``String last = vec.get(vec.size() - ``1``);`   `            ``if` `(last.equals(endWord)) {` `                ``if` `(ans.size() == ``0``) {` `                    ``//1st time` `                    ``ans.add(vec);` `                ``}` `                ``//we have one or more` `                ``else` `if` `(ans.get(``0``).size() == vec.size()) {` `                    ``//same len then add it` `                    ``ans.add(vec);` `                ``}` `            ``}`   `            ``for` `(``int` `i = ``0``; i < last.length(); i++) {` `                ``char``[] arr = last.toCharArray();` `                ``char` `org = arr[i];` `                ``for` `(``char` `ch = ``'a'``; ch <= ``'z'``; ch++) {` `                    ``arr[i] = ch;` `                    ``String newStr = ``new` `String(arr);` `                    ``if` `(vis.contains(newStr)) {` `                        ``//its there` `                        ``List tempVec = ``new` `ArrayList<>(vec);` `                        ``tempVec.add(newStr);` `                        ``qu.add(tempVec);` `                        ``UsedOnLvl.add(newStr); ``// we dont erase now, we do it before next lvl starts` `                    ``}` `                ``}` `                ``//done so replace back to org, hit - ait...zit. Now zit to hit back` `                ``arr[i] = org;` `                ``last = ``new` `String(arr);` `            ``}` `        ``}` `        ``return` `ans;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args) {` `        ``List wordList = ``new` `ArrayList<>();` `        ``wordList.add(``"poon"``);` `        ``wordList.add(``"plee"``);` `        ``wordList.add(``"same"``);` `        ``wordList.add(``"poie"``);` `        ``wordList.add(``"plie"``);` `        ``wordList.add(``"poin"``);` `        ``wordList.add(``"plea"``);`   `        ``String start = ``"toon"``;` `        ``String target = ``"plea"``;`   `        ``List> ans = findSequences(start, target, wordList);` `        ``for` `(List a : ans) {` `            ``for` `(String s : a) {` `                ``System.out.print(s + ``" "``);` `            ``}` `            ``System.out.println(``"\nLength of sequence is "` `+ a.size());` `        ``}` `    ``}` `}`

## Python3

 `from` `typing ``import` `List` `from` `collections ``import` `deque`   `def` `findSequences(beginWord: ``str``, endWord: ``str``, wordList: ``List``[``str``]) ``-``> ``List``[``List``[``str``]]:` `    ``# Initialize the variables` `    ``ans ``=` `[]  ``# list to hold the answer` `    ``vis ``=` `set``(wordList)  ``# set to keep track of visited words` `    ``usedOnLvl ``=` `[]  ``# list to hold the words used on the current level` `    ``q ``=` `deque()  ``# deque to implement the BFS` `    ``q.append([beginWord])  ``# start the BFS with the initial word` `    ``level ``=` `0`  `# current level` `    `  `    ``# Implement BFS` `    ``while` `q:` `        ``vec ``=` `q.popleft()  ``# get the first word in the deque` `        ``if` `len``(vec) > level:` `            ``level ``+``=` `1` `            ``for` `str` `in` `usedOnLvl:` `                ``vis.remove(``str``)  ``# remove the words used on the current level from the visited set` `            ``usedOnLvl ``=` `[]  ``# reset the list of words used on the current level` `        `  `        ``last ``=` `vec[``-``1``]  ``# get the last word in the sequence` `        ``if` `last ``=``=` `endWord:` `            ``if` `not` `ans:` `                ``ans.append(vec)  ``# if the answer is empty, add the sequence` `            ``elif` `len``(ans[``0``]) ``=``=` `len``(vec):` `                ``ans.append(vec)  ``# if the length of the sequence is equal to the first sequence in the answer, add the sequence` `        `  `        ``for` `i ``in` `range``(``len``(last)):` `            ``org ``=` `last[i]  ``# store the original character` `            ``for` `c ``in` `'abcdefghijklmnopqrstuvwxyz'``:` `                ``last ``=` `last[:i] ``+` `c ``+` `last[i``+``1``:]  ``# replace the current character with a new character` `                ``if` `last ``in` `vis:` `                    ``vec.append(last)  ``# add the new word to the sequence` `                    ``q.append(vec.copy())  ``# add the new sequence to the deque` `                    ``vec.pop()  ``# remove the new word from the sequence` `                    ``usedOnLvl.append(last)  ``# add the new word to the list of words used on the current level` `            ``last ``=` `last[:i] ``+` `org ``+` `last[i``+``1``:]  ``# restore the original character` `    `  `    ``return` `ans  ``# return the answer`     `# Test the function with the given example` `wordList ``=` `[``"poon"``, ``"plee"``, ``"same"``, ``"poie"``, ``"plie"``, ``"poin"``, ``"plea"``]` `start ``=` `"toon"` `target ``=` `"plea"` `ans ``=` `findSequences(start, target, wordList)` `for` `a ``in` `ans:` `    ``print``(``*``a, f``"\nLength of sequence is {len(a)}\n"``)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `Program` `{` `  ``// Function to return the sequences itself` `  ``static` `List> findSequences(``string` `beginWord, ` `                                          ``string` `endWord, ` `                                          ``List<``string``> wordList)` `  ``{` `    ``List> ans = ``new` `List>();` `    ``HashSet<``string``> vis = ``new` `HashSet<``string``>(wordList);` `    ``List<``string``> UsedOnLvl = ``new` `List<``string``>();` `    ``Queue> qu = ``new` `Queue>();` `    ``qu.Enqueue(``new` `List<``string``> { beginWord });` `    ``int` `level = 0;`   `    ``while` `(qu.Count > 0)` `    ``{` `      ``List<``string``> vec = qu.Dequeue();` `      ``if` `(vec.Count > level)` `      ``{` `        ``level++;`   `        ``//calc for next lvl is gonna happen` `        ``//lvl 0 1 2 3 4 5`   `        ``//also del prev guys used` `        ``//or else infinite loop and not short len (duplication)` `        ``for` `(``int` `i = 0; i < UsedOnLvl.Count; i++)` `        ``{` `          ``vis.Remove(UsedOnLvl[i]);` `        ``}` `        ``UsedOnLvl.Clear();` `      ``}` `      ``string` `last = vec[vec.Count - 1];` `      ``if` `(last == endWord)` `      ``{` `        ``if` `(ans.Count == 0)` `        ``{` `          ``ans.Add(vec);` `        ``}` `        ``else` `if` `(ans[0].Count == vec.Count)` `        ``{` `          ``ans.Add(vec);` `        ``}` `      ``}` `      ``for` `(``int` `i = 0; i < last.Length; i++)` `      ``{` `        ``char` `org = last[i];` `        ``for` `(``char` `ch = ``'a'``; ch <= ``'z'``; ch++)` `        ``{` `          ``last = last.Substring(0, i) + ch + last.Substring(i + 1);` `          ``if` `(vis.Contains(last))` `          ``{` `            ``vec.Add(last);` `            ``qu.Enqueue(``new` `List<``string``>(vec));` `            ``vec.RemoveAt(vec.Count - 1);` `            ``UsedOnLvl.Add(last);` `          ``}` `        ``}` `        ``last = last.Substring(0, i) + org + last.Substring(i + 1);` `      ``}` `    ``}` `    ``return` `ans;` `  ``}`   `  ``static` `void` `Main(``string``[] args)` `  ``{` `    ``List<``string``> wordList = ``new` `List<``string``>();` `    ``wordList.Add(``"poon"``);` `    ``wordList.Add(``"plee"``);` `    ``wordList.Add(``"same"``);` `    ``wordList.Add(``"poie"``);` `    ``wordList.Add(``"plie"``);` `    ``wordList.Add(``"poin"``);` `    ``wordList.Add(``"plea"``);`   `    ``string` `start = ``"toon"``;` `    ``string` `target = ``"plea"``;`   `    ``List> ans = findSequences(start, target, wordList);` `    ``foreach` `(List<``string``> a ``in` `ans)` `    ``{` `      ``foreach` `(``string` `s ``in` `a)` `      ``{` `        ``Console.Write(s + ``" "``);` `      ``}` `      ``Console.WriteLine(``"\nLength of sequence is "` `+ a.Count);` `    ``}` `  ``}` `}`

## Javascript

 `// Javascript program for the above approach`   `function` `findSequences(beginWord, endWord, wordList) {` `  ``let ans = []; ``// list to hold the answer` `  ``let vis = ``new` `Set(wordList); ``// set to keep track of visited words` `  ``let usedOnLvl = []; ``// list to hold the words used on the current level` `  ``let q = []; ``// array to implement the BFS` `  ``q.push([beginWord]); ``// start the BFS with the initial word` `  ``let level = 0; ``// current level`   `  ``// Implement BFS` `  ``while` `(q.length) {` `    ``let vec = q.shift(); ``// get the first word in the array` `    ``if` `(vec.length > level) {` `      ``level += 1;` `      ``for` `(let str of usedOnLvl) {` `        ``vis.``delete``(str); ``// remove the words used on the current level from the visited set` `      ``}` `      ``usedOnLvl = []; ``// reset the list of words used on the current level` `    ``}`   `    ``let last = vec[vec.length - 1]; ``// get the last word in the sequence` `    ``if` `(last == endWord) {` `      ``if` `(!ans.length) {` `        ``ans.push(vec); ``// if the answer is empty, add the sequence` `      ``} ``else` `if` `(ans[0].length == vec.length) {` `        ``ans.push(vec); ``// if the length of the sequence is equal to the first sequence in the answer, add the sequence` `      ``}` `    ``}`   `    ``for` `(let i = 0; i < last.length; i++) {` `      ``let org = last[i]; ``// store the original character` `      ``for` `(let c of ``'abcdefghijklmnopqrstuvwxyz'``) {` `        ``last = last.slice(0, i) + c + last.slice(i + 1); ``// replace the current character with a new character` `        ``if` `(vis.has(last)) {` `          ``vec.push(last); ``// add the new word to the sequence` `          ``q.push(vec.slice()); ``// add the new sequence to the array` `          ``vec.pop(); ``// remove the new word from the sequence` `          ``usedOnLvl.push(last); ``// add the new word to the list of words used on the current level` `        ``}` `      ``}` `      ``last = last.slice(0, i) + org + last.slice(i + 1); ``// restore the original character` `    ``}` `  ``}`   `  ``return` `ans; ``// return the answer` `}`   `// Test the function with the given example` `let wordList = [``"poon"``, ``"plee"``, ``"same"``, ``"poie"``, ``"plie"``, ``"poin"``, ``"plea"``];` `let start = ``"toon"``;` `let target = ``"plea"``;` `let ans = findSequences(start, target, wordList);` `for` `(let a of ans) {` `  ``console.log(...a, `\nLength of sequence is \${a.length}\n`);` `}`   `// This code is contributed by princekumaras`

Output

```toon poon poin poie plie plee plea
Length of sequence is 7```

Time Complexity: O(N*M*26)

Auxiliary Space: O(N*M)

where N = length of wordList and M = | wordList[i] |

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next