diff --git a/Word Ladder/Word_Ladder_I.cpp b/Word Ladder/Word_Ladder_I.cpp new file mode 100644 index 00000000..3c728501 --- /dev/null +++ b/Word Ladder/Word_Ladder_I.cpp @@ -0,0 +1,89 @@ +// Word Ladder I +// Problem statement: +/* + Given two distinct words startWord and targetWord, and a list denoting wordList of unique words of equal lengths. Find the length of the shortest transformation sequence from startWord to targetWord. + Keep the following conditions in mind: + + -> A word can only consist of lowercase characters. + -> Only one letter can be changed in each transformation. + -> Each transformed word must exist in the wordList including the targetWord. + -> startWord may or may not be part of the wordList. + + If no possible way to transform sequence from startWord to targetWord return 0. +*/ +// Test Case: + +/* +Input: +wordList = {"des","der","dfr","dgt","dfs"} +startWord = "der", targetWord= "dfs", +Output: +3 +Explanation: +The length of the smallest transformation +sequence from "der" to "dfs" is 3 +i,e "der" -> "dfr" -> "dfs". +*/ + +#include +using namespace std; + +class Solution { +public: + // TC -> O(N) [wordList length] * O(word length) * O(26) * O(logN) [set] + int ladderLength(string beginWord, string endWord, vector& wordList) { + queue> q; + // converting vector of wordList to set of wordList + // because it is easier to search as word in set then in a vector + unordered_set s(wordList.begin(), wordList.end()); + + q.push({beginWord, 1}); // holds the beginning word and initial step as 1 + + // we are deleting the already traversed word because forming the same word again + // has no point, we want to form the new words and not loop witing the same set of words + s.erase(beginWord); + + while(!q.empty()){ + string word = q.front().first; + int steps = q.front().second; + q.pop(); + if(word == endWord) return steps; + + // traverse through all the characters of the word + for(int i = 0; i < word.size(); i++){ + + string original = word; + + // change each character to some different letters from a-z + for(char ch = 'a'; ch <= 'z'; ch++) + { + word[i] = ch; + + // if any of the word exist in wordList we will take that word + if(s.count(word)){ + s.erase(word); + q.push({word, steps+1}); + } + } + word = original; // undo the changes made. + } + } + return 0; + } +}; +int main(){ + int tc; + cin >> tc; + while(tc--){ + int n; + cin >> n; + vectorwordList(n); + for(int i = 0; i < n; i++)cin >> wordList[i]; + string startWord, targetWord; + cin >> startWord >> targetWord; + Solution obj; + int ans = obj.ladderLength(startWord, targetWord, wordList); + cout << ans << "\n"; + } + return 0; +} \ No newline at end of file diff --git a/Word Ladder/Word_Ladder_II.cpp b/Word Ladder/Word_Ladder_II.cpp new file mode 100644 index 00000000..2149be1c --- /dev/null +++ b/Word Ladder/Word_Ladder_II.cpp @@ -0,0 +1,126 @@ +// Word Ladder II +// Problem statement: +/* +Given two distinct words startWord and targetWord, and a list denoting wordList of unique words of equal lengths. Find all shortest transformation sequence(s) from startWord to targetWord. You can return them in any order possible. +Keep the following conditions in mind: + +-> A word can only consist of lowercase characters. +-> Only one letter can be changed in each transformation. +-> Each transformed word must exist in the wordList including the targetWord. +-> startWord may or may not be part of the wordList. +-> Return an empty list if there is no such transformation sequence. +*/ + +// Test Case: +/* +Input: +startWord = "der", targetWord = "dfs", +wordList = {"des","der","dfr","dgt","dfs"} +Output: +der dfr dfs +der des dfs +Explanation: +The length of the smallest transformation is 3. +And the following are the only two ways to get +to targetWord:- +"der" -> "des" -> "dfs". +"der" -> "dfr" -> "dfs". +*/ + +#include +using namespace std; + +class Solution { +public: + vector> findSequences(string beginWord, string endWord, vector& wordList) { + unordered_set st(wordList.begin(), wordList.end()); + queue> q; + q.push({beginWord}); + // stores used words from wordList of previous level + vector usedOnLevel; + usedOnLevel.push_back(beginWord); + int level = 0; + vector> ans; + while(!q.empty()) + { + // stores the current level word sequence + vector v = q.front(); + q.pop(); + + // erase all the words that has been + // used in the previous level to transform + while(v.size() > level) + { + level++; + for(auto it: usedOnLevel) + st.erase(it); + } + + string word = v.back(); + if(word == endWord) + ans.push_back(v); + for(int i = 0; i < word.size(); i++) + { + char original = word[i]; + for(char ch = 'a'; ch <= 'z'; ch++){ + word[i] = ch; + if(st.count(word)) + { + // if transformed word exists in wordList + // add it to the sequence + v.push_back(word); + q.push(v); + + // mark the word as visited on that level + usedOnLevel.push_back(word); + // undo the changes made in word sequenece + // so that it can be changed to some other word + // on the same level + v.pop_back(); + } + } + word[i] = original; // undo the character changes + } + } + return ans; + } +}; +bool comp(vector a, vector b) +{ + string x = "", y = ""; + for(string i: a) + x += i; + for(string i: b) + y += i; + + return x> tc; + while(tc--){ + int n; + cin >> n; + vectorwordList(n); + for(int i = 0; i < n; i++)cin >> wordList[i]; + string startWord, targetWord; + cin >> startWord >> targetWord; + Solution obj; + vector> ans = obj.findSequences(startWord, targetWord, wordList); + if(ans.size()==0) + cout<<-1<