Word ladder
Given two words (StartAndEnd), And a dictionary, find the length of shortest transformation sequence fromStartToEnd, Such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:Start="hit"
End="cog"
Dict=["hot","dot","dog","lot","log"]
As one shortest transformation is"hit" -> "hot" -> "dot" -> "dog" -> "cog"
, Return its length5
.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
Idea: Search for BFS in width first. (You can search from the beginning to the end, or from the end to the head ,).
In my solution, two hash_sets are used to store the current layer and the next layer of nodes, and the other hash_set stores the previously traversed nodes.
class Solution {public:int ladderLength(string start, string end, unordered_set<string> &dict) {int ans = 0;unordered_set<string> previousNodes;vector<unordered_set<string> > node_levels(2);int curLevel = 0; // which is index belong to vector node_levels.node_levels[curLevel].insert(end);ans++;unordered_set<string>::iterator it;while(!node_levels[curLevel].empty()) {for(it = node_levels[curLevel].begin(); it != node_levels[curLevel].end(); ++it) {for(size_t i = 0; i < it->size(); ++i) {string node(*it);for(node[i] = ‘a‘; node[i] <= ‘z‘; ++node[i]) {if(node == start) return (ans+1); // output 1if(previousNodes.count(node) || node_levels[curLevel].count(node) || node[i] == (*it)[i] || !dict.count(node)) continue;node_levels[!curLevel].insert(node);}}previousNodes.insert(*it);}node_levels[curLevel].clear();curLevel = !curLevel;ans++;}return 0; // output 2}};
Word ladder II
Given two words (StartAndEnd), And a dictionary, find all shortest transformation sequence (s) fromStartToEnd, Such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:Start="hit"
End="cog"
Dict=["hot","dot","dog","lot","log"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
Thought: On the basis of I, add hash_map to write down each edge, start searching from end, create a graph with start as the Source Vertex and end as the sink vertex, and then start searching from start.
typedef pair<string, string> PAIR;void getSolution(string &end, string& word, unordered_multimap<string, string> &map, vector<vector<string> > &vec, vector<string> &vec2) {if(word == end) {vec.push_back(vec2);vec.back().push_back(word);return;}pair<unordered_map<string, string>::iterator, unordered_map<string, string>::iterator> ret;ret = map.equal_range(word);while(ret.first != ret.second) {vec2.push_back(ret.first->first);getSolution(end, ret.first->second, map, vec, vec2);vec2.pop_back();ret.first++;}}class Solution {public:vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {vector<vector<string>> vec;unordered_multimap<string, string> edges;unordered_set<string> previousNodes; vector<unordered_set<string> > node_levels(2);int curLevel = 0; // an index belong to vector node_levelsnode_levels[curLevel].insert(end);unordered_set<string>::iterator it;while(!node_levels[curLevel].empty() && node_levels[curLevel].count(start) == 0) {for(it = node_levels[curLevel].begin(); it != node_levels[curLevel].end(); ++it) {for(size_t i = 0; i < it->size(); ++i) {string node(*it);for(node[i] = ‘a‘; node[i] <= ‘z‘; ++node[i]) {if(node == start) { node_levels[1-curLevel].insert(node);edges.insert(PAIR(start, *it));break;}if(previousNodes.count(node) || node_levels[curLevel].count(node) || dict.count(node) == 0) continue;node_levels[1-curLevel].insert(node);edges.insert(PAIR(node, *it));}}previousNodes.insert(*it);}node_levels[curLevel].clear();curLevel = !curLevel;}previousNodes.clear();if(node_levels[curLevel].empty()) return vec;vector<string> vec2;getSolution(end, start, edges, vec, vec2);return vec;}};
18. Word ladder & Word ladder II