-
Notifications
You must be signed in to change notification settings - Fork 707
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
06d4395
commit 6eeb16f
Showing
2 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<bits/stdc++.h> | ||
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<string>& wordList) { | ||
queue<pair<string, int>> 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<string> 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; | ||
vector<string>wordList(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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<bits/stdc++.h> | ||
using namespace std; | ||
|
||
class Solution { | ||
public: | ||
vector<vector<string>> findSequences(string beginWord, string endWord, vector<string>& wordList) { | ||
unordered_set<string> st(wordList.begin(), wordList.end()); | ||
queue<vector<string>> q; | ||
q.push({beginWord}); | ||
// stores used words from wordList of previous level | ||
vector<string> usedOnLevel; | ||
usedOnLevel.push_back(beginWord); | ||
int level = 0; | ||
vector<vector<string>> ans; | ||
while(!q.empty()) | ||
{ | ||
// stores the current level word sequence | ||
vector<string> 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<string> a, vector<string> b) | ||
{ | ||
string x = "", y = ""; | ||
for(string i: a) | ||
x += i; | ||
for(string i: b) | ||
y += i; | ||
|
||
return x<y; | ||
} | ||
int main(){ | ||
int tc; | ||
cin >> tc; | ||
while(tc--){ | ||
int n; | ||
cin >> n; | ||
vector<string>wordList(n); | ||
for(int i = 0; i < n; i++)cin >> wordList[i]; | ||
string startWord, targetWord; | ||
cin >> startWord >> targetWord; | ||
Solution obj; | ||
vector<vector<string>> ans = obj.findSequences(startWord, targetWord, wordList); | ||
if(ans.size()==0) | ||
cout<<-1<<endl; | ||
else | ||
{ | ||
sort(ans.begin(), ans.end(), comp); | ||
for(int i=0; i<ans.size(); i++) | ||
{ | ||
for(int j=0; j<ans[i].size(); j++) | ||
{ | ||
cout<<ans[i][j]<<" "; | ||
} | ||
cout<<endl; | ||
} | ||
} | ||
} | ||
return 0; | ||
} |