LeetCode-127. Word Ladderhttps://leetcode.com/problems/word-ladder/
题目描述
A transformation sequence from word beginWord
to word endWord
using a dictionary wordList
is a sequence of words beginWord -> s1 -> s2 -> ... -> sk
such that:
- Every adjacent pair of words differs by a single letter.
- Every
si
for1 <= i <= k
is inwordList
. Note thatbeginWord
does not need to be inwordList
. sk == endWord
Given two words, beginWord
and endWord
, and a dictionary wordList
, return the number of words in the shortest transformation sequence from beginWord
to endWord
, or 0
if no such sequence exists.
Example 1:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: One shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> cog", which is 5 words long.
Example 2:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"] Output: 0 Explanation: The endWord "cog" is not in wordList, therefore there is no valid transformation sequence.
解题思路
BFS
【C++解法】
1. map + queue
此处仅限于计数
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_map<string, vector<string>> mp;
for(string& w:wordList) for(int i=0; i<w.size(); i++) mp[w.substr(0, i) + "#" + w.substr(i+1)].push_back(w);
int ans = 1;
queue<string> q;
q.push(beginWord);
while(!q.empty()){
ans++;
queue<string> nq;
while(!q.empty()){
string s = q.front(); q.pop();
for(int i=0; i<s.size(); i++){
string key = s.substr(0, i) + "#" + s.substr(i+1);
if(mp.count(key)){
for(string& ns:mp[key]){
if(ns==endWord) return ans;
nq.push(ns);
}
}
mp.erase(key);
}
}
swap(q, nq);
}
return 0;
}
};
2. three set
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> dict(wordList.begin(), wordList.end());
if(!dict.count(endWord)) return 0;
unordered_set<string> forward;
forward.insert(beginWord);
unordered_set<string> backward;
backward.insert(endWord);
unordered_set<string> next;
int steps = 0;
while (!forward.empty() && !backward.empty()) {
++steps;
if (forward.size() > backward.size()) swap(forward, backward);
for (auto &word : forward) dict.erase(word);
for (auto &word: backward) dict.erase(word);
for (string word : forward) {
for (int i = 0; i < word.length(); ++i) {
const char c = word[i];
for (int j = 'a'; j <= 'z'; ++j) {
if (c == j) continue;
word[i] = j;
if (backward.count(word)) return steps + 1; //恰好相邻
if (!dict.count(word)) continue; //都不存在
next.insert(word);
}
word[i] = c;
}
}
swap(forward, next);
next.clear();
}
return 0;
}
};
3. set + queue
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> dict(wordList.begin(),wordList.end());
if (dict.find(endWord) == dict.end()) {return 0;}
queue<string> q;
q.push(beginWord);
int len = 1;
while (!q.empty()){
int size = q.size();
while (size--){
string last = q.front(); q.pop();
if (last == endWord) {return len;}
dict.erase(last);
for (int i=0; i<last.size(); i++){
string temp = last;
for (char ch='a'; ch<='z'; ch++){
temp[i] = ch;
if (dict.find(temp) != dict.end()){
q.push(temp);
}
}
}
}
++len;
}
return 0;
}
};
【Java解法】
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> dict = new LinkedHashSet<>(wordList);
if (!dict.contains(endWord)) {return 0;}
Queue<String> q = new LinkedList();
q.offer(beginWord);
int len = 1;
while (!q.isEmpty()){
int sz = q.size();
while (sz-- > 0){
String last = q.poll();
if (last.equals(endWord)) {return len;}
dict.remove(last);
for (int i=0; i<last.length(); i++) {
char[] temp = last.toCharArray();
for (char c='a'; c<='z'; c++) {
temp[i]=c;
String s1 = String.valueOf(temp);
if (dict.contains(s1)){
q.offer(s1);
}
}
}
}
len++;
}
return 0;
}
}