您的位置:首页 > 其它

【Leetcode】 Word Ladder

2017-11-11 20:47 246 查看
题目:

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
Only one letter can be changed at a time.
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

For example,

Given:
beginWord = 
"hit"

endWord = 
"cog"

wordList = 
["hot","dot","dog","lot","log","cog"]


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.
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.
分析:

先把起点加到队列中, 然后每次将字典中与队首距离为1的字符串加进队列, 直到最后出队列的是终点字符串, 为确保终点字符串存在, 我们可以先在字典中加进去终点字符串。而在本题中,在寻找与一个字符串相距为1的的字典中另一个字符串时,如果一个个遍历字典消耗时间比较多, 每次时间复杂度是O(n).。在单个字符串不是很长的情况下, 一个个查看改变一个字符然后在字典中查看是否存在效率要更高些, 其时间复杂度是O(k log n), 其中k为单个字符串长度, n为字典长度。

Java版本:

public int ladderLength(String beginWord, String endWord, Set<String> wordDict) {
Set<String> reached = new HashSet<String>();
reached.add(beginWord);
wordDict.add(endWord);
int distance = 1;
while (!reached.contains(endWord)) {
Set<String> toAdd = new HashSet<String>();
for (String each : reached) {
for (int i = 0; i < each.length(); i++) {
char[] chars = each.toCharArray();
for (char ch = 'a'; ch <= 'z'; ch++) {
chars[i] = ch;
String word = new String(chars);
if (wordDict.contains(word)) {
toAdd.add(word);
wordDict.remove(word);
}
}
}
}
distance++;
if (toAdd.size() == 0) return 0;
reached = toAdd;
}
return distance;
}
C++版本:

class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
wordList.insert(endWord);
queue<pair<string, int>> que;
que.push(make_pair(beginWord, 1));
wordList.erase(wordList.find(beginWord));
while(!que.empty())
{
auto val = que.front();
que.pop();
if(val.first == endWord) return val.second;
for(int i =0; i< val.first.size(); i++)
{
string str = val.first;
for(int j = 0; j < 26; j++)
{
str[i] = 'a'+j;
if(wordList.count(str) == 1)
{
que.push(make_pair(str, val.second+1));
wordList.erase(str);
}
}
}
}
return 0;
}
};

Python版本:
from collections import deque

class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):

def construct_dict(word_list):
d = {}
for word in word_list:
for i in range(len(word)):
s = word[:i] + "_" + word[i+1:]
d[s] = d.get(s, []) + [word]
return d

def bfs_words(begin, end, dict_words):
queue, visited = deque([(begin, 1)]), set()
while queue:
word, steps = queue.popleft()
if word not in visited:
visited.add(word)
if word == end:
return steps
for i in range(len(word)):
s = word[:i] + "_" + word[i+1:]
neigh_words = dict_words.get(s, [])
for neigh in neigh_words:
if neigh not in visited:
queue.append((neigh, steps + 1))
return 0

d = construct_dict(wordList | set([beginWord, endWord]))
return bfs_words(beginWord, endWord, d)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: