Word Ladder 题解
题目来源:Word Ladder
>
Given two words (start and end), and a dictionary, find the length of shortest
transformation sequence from start to end, 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 length 5.
Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
解题思路:
bfs
用BFS搜索,记录从开始到当前路径长度。注意遍历map/set删除满足条件的element的写法。第一个用BFS搜索到的肯定是最短的之一。DFS则不是哦。
bool diff1char(string s1, string s2)
{
assert(s1.length() == s2.length());
int diff = 0;
for(int i = 0; i < s1.length(); i++)
if (s1[i] != s2[i]) {
++diff;
if(diff == 2) return false;
}
return true;
}
int ladderLength(string start, string end, unordered_set<string> &dict)
{
queue<std::pair<string,int>> queues;
queues.push(std::pair<string, int>(start,1));
auto it = dict.find(start);
if(it != dict.end()) dict.erase(start);
while (queues.size() > 0)
{
string s = queues.front().first;
int curLen = queues.front().second;
queues.pop();
if (diff1char(s, end))
return curLen + 1;
for(auto it = dict.begin(); it != dict.end(); )
{
if (diff1char(s, *it))
{
queues.push(std::pair<string, int>(*it, curLen+1));
it = dict.erase(it);
}else
++it;
}
}
return -1;
}
悲剧的是,上面的过不了~ testcase中dict太大,而word相对较短,去从dict去搜索相邻的单词,耗时太久。改为变动word中的每一个字符(26个一个一个试),然后再去dict中判断是否存在。这样就能AC。ref, 代码如下:
void getDiff1chars(string s1, queue<std::pair<string,int>> &next, int nextLen, unordered_set<string> &dict)
{
int n = s1.length();
for(int i = 0; i < n; i++)
{
string s2(s1);
for(char c = 'a'; c <= 'z'; c++)
{
if(s2[i] != c){
s2[i] = c;
auto it = dict.find(s2);
if(it != dict.end())
{
next.push(std::pair<string,int>(s2, nextLen));
dict.erase(it);
}
}
}
}
}
int ladderLength(string start, string end, unordered_set<string> &dict)
{
queue<std::pair<string,int>> queues;
queues.push(std::pair<string, int>(start,1));
auto it = dict.find(start);
if(it != dict.end()) dict.erase(start);
while (queues.size() > 0)
{
string s = queues.front().first;
int curLen = queues.front().second;
queues.pop();
if (diff1char(s, end))
return curLen + 1;
getDiff1chars(s, queues, curLen+1, dict);
}
return 0;
}
Last updated
Was this helpful?