Print all possible shortest chains to reach a target word

Last Updated : 06 Mar, 2023

Given two strings start and target(both of the same length) and a list of strings str[], the task is to print all possible smallest sequences starting from start to target if it exists, such that adjacent words in the sequence only differ by a single character and each word in the sequence is present in the given list.

Note: It may be assumed that the target word is present in the list and the length of all the words is the same. If multiple sequences occur, print all of them.

Example:

Input: str[] = {poon, plee, same, poie, plea, plie, poin}, start = “toon”, target = “plea”
Output: [[toon, poon, poin, poie, plee, plea]]
Explanation: toon ? poon ? poin ? poie ? plee ? plea

Input: str[] = { ted, tex, red, tax, tad, den, rex, pee}, start = “red”, target = “tax”
Output [[“red”, “ted”, “tad”, “tax”], [“red”, “ted”, “tex”, “tax”], [“red”, “rex”, “tex”, “tax”]]

Approach: The problem can be solved using BFS.The tricky part here is to do the BFS of the path instead of words. Follow the steps below to solve the problem:

1. Initialize a variable, say res, to store all possible shortest paths.
2. Create a Set to store all the visited words in current path and once the current path is completed, erase all the visited words.
3. For each current word, find the possible next words present in str[] by changing each character from ‘a’ to ‘z’ and find all possible paths.
4. Finally, print all the possible path.

C++

 `// C++ Program to implement` `// the above approach` `#include ` `using` `namespace` `std;`   `// Function to print all possible shortest` `// sequences starting from start to target.` `void` `displaypath(vector >& res)` `{` `    ``for` `(``int` `i = 0; i < res.size(); i++) {` `        ``cout << ``"[ "``;` `        ``for` `(``int` `j = 0; j < res[0].size(); j++) {` `            ``cout << res[i][j] << ``", "``;` `        ``}` `        ``cout << ``" ]\n"``;` `    ``}` `}` `// Find words differing by a single` `// character with word` `vector addWord(` `    ``string word,` `    ``unordered_set& dict)` `{` `    ``vector res;`   `    ``// Find next word in dict by changing` `    ``// each element from 'a' to 'z'` `    ``for` `(``int` `i = 0; i < word.size(); i++) {` `        ``char` `s = word[i];` `        ``for` `(``char` `c = ``'a'``; c <= ``'z'``; c++) {` `            ``word[i] = c;` `            ``if` `(dict.count(word))` `                ``res.push_back(word);` `        ``}` `        ``word[i] = s;` `    ``}` `    ``return` `res;` `}`   `// Function to get all the shortest possible` `// sequences starting from 'start' to 'target'` `vector > findLadders(` `    ``vector& Dict,` `    ``string beginWord,` `    ``string endWord)` `{` `    ``// Store all the shortest path.` `    ``vector > res;`   `    ``// Store visited words in list` `    ``unordered_set visit;`   `    ``// Queue used to find the shortest path` `    ``queue > q;`   `    ``// Stores the distinct words from given list` `    ``unordered_set dict(Dict.begin(),` `                               ``Dict.end());` `    ``q.push({ beginWord });`   `    ``// Stores whether the shortest` `    ``// path is found or not` `    ``bool` `flag = ``false``;`   `    ``while` `(!q.empty()) {` `        ``int` `size = q.size();` `        ``for` `(``int` `i = 0; i < size; i++) {`   `            ``// Explore the next level` `            ``vector cur = q.front();` `            ``q.pop();` `            ``vector newadd;`   `            ``// Find words differing by a` `            ``// single character` `            ``newadd = addWord(cur.back(), dict);`   `            ``// Add words to the path.` `            ``for` `(``int` `j = 0; j < newadd.size(); j++) {` `                ``vector newline(cur.begin(),` `                                       ``cur.end());`   `                ``newline.push_back(newadd[j]);`   `                ``// Found the target` `                ``if` `(newadd[j] == endWord) {` `                    ``flag = ``true``;` `                    ``res.push_back(newline);` `                ``}`   `                ``visit.insert(newadd[j]);` `                ``q.push(newline);` `            ``}` `        ``}`   `        ``// If already reached target` `        ``if` `(flag) {` `            ``break``;` `        ``}`   `        ``// Erase all visited words.` `        ``for` `(``auto` `it : visit) {` `            ``dict.erase(it);` `        ``}`   `        ``visit.clear();` `    ``}` `    ``return` `res;` `}`   `// Driver Code` `int` `main()` `{` `    ``vector str{ ``"ted"``, ``"tex"``, ``"red"``,` `                        ``"tax"``, ``"tad"``, ``"den"``,` `                        ``"rex"``, ``"pee"` `};` `    ``string beginWord = ``"red"``;` `    ``string endWord = ``"tax"``;`   `    ``vector > res` `        ``= findLadders(str, beginWord, endWord);`   `    ``displaypath(res);` `}`

Java

 `import` `java.util.*;`   `public` `class` `ShortestSequence ` `{` `  `  `    ``// Function to print all possible shortest` `    ``// sequences starting from start to target.` `    ``public` `static` `void` `displaypath(List > res)` `    ``{` `        ``for` `(List list : res) {` `            ``System.out.print(``"[ "``);` `            ``for` `(String word : list) {` `                ``System.out.print(word + ``", "``);` `            ``}` `            ``System.out.println(``" ]"``);` `        ``}` `    ``}`   `    ``// Find words differing by a single` `    ``// character with word` `    ``public` `static` `List addWord(String word,` `                                       ``Set dict)` `    ``{` `        ``List res = ``new` `ArrayList<>();`   `        ``// Find next word in dict by changing` `        ``// each element from 'a' to 'z'` `        ``char``[] chars = word.toCharArray();` `        ``for` `(``int` `i = ``0``; i < word.length(); i++) {` `            ``char` `original = chars[i];` `            ``for` `(``char` `c = ``'a'``; c <= ``'z'``; c++) {` `                ``chars[i] = c;` `                ``String newWord = ``new` `String(chars);` `                ``if` `(dict.contains(newWord)) {` `                    ``res.add(newWord);` `                ``}` `            ``}` `            ``chars[i] = original;` `        ``}` `        ``return` `res;` `    ``}`   `    ``// Function to get all the shortest possible` `    ``// sequences starting from 'start' to 'target'` `    ``public` `static` `List >` `    ``findLadders(List dict, String beginWord,` `                ``String endWord)` `    ``{` `        ``// Store all the shortest path.` `        ``List > res = ``new` `ArrayList<>();`   `        ``// Store visited words in list` `        ``Set visit = ``new` `HashSet<>();`   `        ``// Queue used to find the shortest path` `        ``Queue > q = ``new` `LinkedList<>();`   `        ``// Stores the distinct words from given list` `        ``Set words = ``new` `HashSet<>(dict);` `        ``q.add(Collections.singletonList(beginWord));`   `        ``// Stores whether the shortest` `        ``// path is found or not` `        ``boolean` `flag = ``false``;`   `        ``while` `(!q.isEmpty()) {` `            ``int` `size = q.size();` `            ``for` `(``int` `i = ``0``; i < size; i++) {` `                ``// Explore the next level` `                ``List cur = q.poll();` `                ``List newWords = addWord(` `                    ``cur.get(cur.size() - ``1``), words);`   `                ``// Add words to the path.` `                ``for` `(String newWord : newWords) {` `                    ``List newLine` `                        ``= ``new` `ArrayList<>(cur);` `                    ``newLine.add(newWord);`   `                    ``// Found the target` `                    ``if` `(newWord.equals(endWord)) {` `                        ``flag = ``true``;` `                        ``res.add(newLine);` `                    ``}`   `                    ``visit.add(newWord);` `                    ``q.add(newLine);` `                ``}` `            ``}`   `            ``// If already reached target` `            ``if` `(flag) {` `                ``break``;` `            ``}`   `            ``// Erase all visited words.` `            ``words.removeAll(visit);` `            ``visit.clear();` `        ``}` `        ``return` `res;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``List str` `            ``= Arrays.asList(``"ted"``, ``"tex"``, ``"red"``, ``"tax"``,` `                            ``"tad"``, ``"den"``, ``"rex"``, ``"pee"``);` `        ``String beginWord = ``"red"``;` `        ``String endWord = ``"tax"``;`   `        ``List > res` `            ``= findLadders(str, beginWord, endWord);`   `        ``displaypath(res);` `    ``}` `}`

Python3

 `# Python Program to implement` `# the above approach` `from` `collections ``import` `deque` `from` `typing ``import` `Deque, ``List``, ``Set`   `# Function to print all possible shortest` `# sequences starting from start to target.` `def` `displaypath(res: ``List``[``List``[``str``]]):` `    ``for` `i ``in` `res:` `        ``print``(``"[ "``, end``=``"")` `        ``for` `j ``in` `i:` `            ``print``(j, end``=``", "``)` `        ``print``(``"]"``)`   `# Find words differing by a single` `# character with word` `def` `addWord(word: ``str``, ``Dict``: ``Set``):` `    ``res: ``List``[``str``] ``=` `[]` `    ``wrd ``=` `list``(word)` `    `  `    ``# Find next word in dict by changing` `    ``# each element from 'a' to 'z'` `    ``for` `i ``in` `range``(``len``(wrd)):` `        ``s ``=` `wrd[i]` `        ``c ``=` `'a'` `        ``while` `c <``=` `'z'``:` `            ``wrd[i] ``=` `c` `            ``if` `''.join(wrd) ``in` `Dict``:` `                ``res.append(''.join(wrd))` `            ``c ``=` `chr``(``ord``(c) ``+` `1``)` `        ``wrd[i] ``=` `s` `    ``return` `res`   `# Function to get all the shortest possible` `# sequences starting from 'start' to 'target'` `def` `findLadders(Dictt: ``List``[``str``], beginWord: ``str``, endWord: ``str``):`   `    ``# Store all the shortest path.` `    ``res: ``List``[``List``[``str``]] ``=` `[]`   `    ``# Store visited words in list` `    ``visit ``=` `set``()`   `    ``# Queue used to find the shortest path` `    ``q: Deque[``List``[``str``]] ``=` `deque()`   `    ``# Stores the distinct words from given list` `    ``Dict` `=` `set``()` `    ``for` `i ``in` `Dictt:` `        ``Dict``.add(i)` `    ``q.append([beginWord])`   `    ``# Stores whether the shortest` `    ``# path is found or not` `    ``flag ``=` `False` `    ``while` `q:` `        ``size ``=` `len``(q)` `        ``for` `i ``in` `range``(size):`   `            ``# Explore the next level` `            ``cur ``=` `q[``0``]` `            ``q.popleft()` `            ``newadd ``=` `[]`   `            ``# Find words differing by a` `            ``# single character` `            ``newadd ``=` `addWord(cur[``-``1``], ``Dict``)`   `            ``# Add words to the path.` `            ``for` `j ``in` `range``(``len``(newadd)):` `                ``newline ``=` `cur.copy()` `                ``newline.append(newadd[j])`   `                ``# Found the target` `                ``if` `(newadd[j] ``=``=` `endWord):` `                    ``flag ``=` `True` `                    ``res.append(newline)`   `                ``visit.add(newadd[j])` `                ``q.append(newline)`   `        ``# If already reached target` `        ``if` `(flag):` `            ``break`   `        ``# Erase all visited words.` `        ``for` `it ``in` `visit:` `            ``Dict``.remove(it)` `        ``visit.clear()` `    ``return` `res`   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:`   `    ``string ``=` `[``"ted"``, ``"tex"``, ``"red"``, ``"tax"``, ``"tad"``, ``"den"``, ``"rex"``, ``"pee"``]` `    ``beginWord ``=` `"red"` `    ``endWord ``=` `"tax"`   `    ``res ``=` `findLadders(string, beginWord, endWord)`   `    ``displaypath(res)`   `# This code is contributed by sanjeev2552`

C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `Program ` `{`   `  ``// Function to print all possible shortest` `  ``// sequences starting from start to target.` `  ``static` `void` `DisplayPath(List > res)` `  ``{` `    ``foreach``(``var` `item ``in` `res)` `    ``{` `      ``Console.Write(``"[ "``);` `      ``foreach``(``var` `word ``in` `item)` `      ``{` `        ``Console.Write(word + ``", "``);` `      ``}` `      ``Console.Write(``" ]\n"``);` `    ``}` `  ``}`   `  ``// Find words differing by a single` `  ``// character with word` `  ``static` `List<``string``> AddWord(``string` `word,` `                              ``HashSet<``string``> dict)` `  ``{` `    ``var` `res = ``new` `List<``string``>();`   `    ``// Find next word in dict by changing` `    ``// each element from 'a' to 'z'` `    ``for` `(``int` `i = 0; i < word.Length; i++) {` `      ``char` `s = word[i];` `      ``for` `(``char` `c = ``'a'``; c <= ``'z'``; c++) {` `        ``word = word.Remove(i, 1).Insert(` `          ``i, c.ToString());` `        ``if` `(dict.Contains(word))` `          ``res.Add(word);` `      ``}` `      ``word` `        ``= word.Remove(i, 1).Insert(i, s.ToString());` `    ``}` `    ``return` `res;` `  ``}`   `  ``// Function to get all the shortest possible` `  ``// sequences starting from 'start' to 'target'` `  ``static` `List >` `    ``FindLadders(List<``string``> Dict, ``string` `beginWord,` `                ``string` `endWord)` `  ``{` `    ``// Store all the shortest path.` `    ``var` `res = ``new` `List >();`   `    ``// Store visited words in list` `    ``var` `visit = ``new` `HashSet<``string``>();`   `    ``// Queue used to find the shortest path` `    ``var` `q = ``new` `Queue >();` `    ``q.Enqueue(``new` `List<``string``>{ beginWord });`   `    ``// Stores the distinct words from given list` `    ``var` `dict = ``new` `HashSet<``string``>(Dict);`   `    ``// Stores whether the shortest` `    ``// path is found or not` `    ``bool` `flag = ``false``;`   `    ``while` `(q.Count > 0) {` `      ``int` `size = q.Count;` `      ``for` `(``int` `i = 0; i < size; i++) {` `        ``// Explore the next level` `        ``List<``string``> cur = q.Dequeue();` `        ``var` `newadd` `          ``= AddWord(cur[cur.Count - 1], dict);`   `        ``// Add words to the path.` `        ``foreach``(``var` `word ``in` `newadd)` `        ``{` `          ``var` `newline = ``new` `List<``string``>(cur);`   `          ``newline.Add(word);`   `          ``// Found the target` `          ``if` `(word == endWord) {` `            ``flag = ``true``;` `            ``res.Add(newline);` `          ``}`   `          ``visit.Add(word);` `          ``q.Enqueue(newline);` `        ``}` `      ``}`   `      ``// If already reached target` `      ``if` `(flag) {` `        ``break``;` `      ``}`   `      ``// Erase all visited words.` `      ``foreach``(``var` `item ``in` `visit)` `      ``{` `        ``dict.Remove(item);` `      ``}`   `      ``visit.Clear();` `    ``}` `    ``return` `res;` `  ``}`   `  ``// Driver Code` `  ``static` `void` `Main(``string``[] args)` `  ``{` `    ``var` `str = ``new` `List<``string``>{ ``"ted"``, ``"tex"``, ``"red"``,` `                               ``"tax"``, ``"tad"``, ``"den"``,` `                               ``"rex"``, ``"pee"` `};` `    ``var` `beginWord = ``"red"``;` `    ``var` `endWord = ``"tax"``;`   `    ``var` `res = FindLadders(str, beginWord, endWord);`   `    ``DisplayPath(res);` `  ``}` `}`

Javascript

 `//  JavaScript Program to implement`   `  ``// Find words differing by a single` `  ``// character with word` `function` `addWord(word, dict) {` `  ``const res = [];`   `  ``// Find next word in dict by changing` `  ``// each element from 'a' to 'z'` `  ``for` `(let i = 0; i < word.length; i++) {` `    ``const s = word[i];` `    ``for` `(let c = 97; c <= 122; c++) {` `      ``word = word.substr(0, i) + String.fromCharCode(c) + word.substr(i + 1);` `      ``if` `(dict.has(word)) {` `        ``res.push(word);` `      ``}` `    ``}` `    ``word = word.substr(0, i) + s + word.substr(i + 1);` `  ``}` `  ``return` `res;` `}` ` ``// Function to get all the shortest possible` `  ``// sequences starting from 'start' to 'target'`   `function` `findLadders(dict, beginWord, endWord) {` `  ``// Store all the shortest path.` `  ``const res = [];`   `  ``// Store visited words in set.` `  ``const visit = ``new` `Set();`   `  ``// Queue used to find the shortest path` `  ``const q = [ [beginWord] ];`   `  ``// Stores the distinct words from given list` `  ``const dictSet = ``new` `Set(dict);`   `  ``// Stores whether the shortest path is found or not` `  ``let flag = ``false``;`   `  ``while` `(q.length > 0) {` `    ``const size = q.length;` `    ``for` `(let i = 0; i < size; i++) {` `      ``// Explore the next level` `      ``const cur = q.shift();` `      ``const newAdd = addWord(cur[cur.length - 1], dictSet);`   `      ``// Add words to the path` `      ``for` `(const word of newAdd) {` `        ``const newLine = [...cur, word];`   `        ``// Found the target` `        ``if` `(word === endWord) {` `          ``flag = ``true``;` `          ``res.push(newLine);` `        ``}`   `        ``visit.add(word);` `        ``q.push(newLine);` `      ``}` `    ``}`   `    ``// If already reached target` `    ``if` `(flag) {` `      ``break``;` `    ``}`   `    ``// Erase all visited words` `    ``for` `(const item of visit) {` `      ``dictSet.``delete``(item);` `    ``}`   `    ``visit.clear();` `  ``}`   `  ``return` `res;` `}`   `function` `displayPath(res) {` `  ``for` `(const item of res) {` `    ``process.stdout.write(``"[ "``);` `    ``for` `(const word of item) {` `      ``process.stdout.write(word + ``", "``);` `    ``}` `    ``process.stdout.write(``" ]\n"``);` `  ``}` `}`   `// Driver code` `const dict = [``"ted"``, ``"tex"``, ``"red"``, ``"tax"``, ``"tad"``, ``"den"``, ``"rex"``, ``"pee"``];` `const beginWord = ``"red"``;` `const endWord = ``"tax"``;`   `const res = findLadders(dict, beginWord, endWord);` `displayPath(res);`   `// This code is contributed by rutikbhosale`

Output:

```[ red, ted, tad, tax,  ]
[ red, ted, tex, tax,  ]
[ red, rex, tex, tax,  ]```

Time complexity: O(NÂ²*M), where M is the number of strings in the given list and N is the length of each string.

Auxiliary Space:O(M*N)

Previous
Next