#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <queue>
#include <unordered_map>
using namespace std;
/*
问题:
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
输入:
hit cog 6
hot dot dog lot log cog
hit cog 5
hot dot dog lot log
输出:
5
0
*/
class Solution {
public:
vector<string> getOneEditWords(string& word , unordered_map<string,int>& words , unordered_map<string , vector<string> >& wordToNextWords)
{
vector<string> nextWords;
if(word.empty())
{
return nextWords;
}
if(1 == wordToNextWords.count(word))
{
return wordToNextWords[word];
}
int len = word.length();
char temp;
for(int i = 0; i < len ; i++)
{
temp = word.at(i);
for(char ch = 'a' ; ch <= 'z' ; ch++)
{
word.at(i) = ch;
if(1 == words.count(word))
{
nextWords.push_back(word);
}
word.at(i) = temp;
}
}
wordToNextWords[word] = nextWords;
return nextWords;
}
int bfs(string beginWord, string endWord , vector<string>& wordList ,
unordered_map<string,int>& words , unordered_map<string , vector<string> >& wordToNextWords)
{
unordered_map<string ,int> strToDistance;
queue<string> queueWords;
queueWords.push(beginWord);
strToDistance[beginWord] = 0;
vector<string> nextWords;
string word;
string nextWord;
int curDistance = 0;
int size;
bool isFind = false;
while(!queueWords.empty())
{
word = queueWords.front();
queueWords.pop();
nextWords = getOneEditWords(word ,words , wordToNextWords);
if(nextWords.empty())
{
continue;
}
curDistance = strToDistance[word];
size = nextWords.size();
for(int i = 0 ; i < size ; i++)
{
nextWord = nextWords.at(i);
//如果没有访问过
if(strToDistance.find(nextWord) == strToDistance.end())
{
strToDistance[nextWord] = curDistance + 1;
queueWords.push(nextWord);
if(nextWord == endWord)
{
isFind = true;
}
}
}
if(isFind)
{
break;
}
}
if(isFind)
{
return (curDistance + 2);//curDistance需要加上从当前字符串到结尾字符串的距离1,以及多1个元素
}
else
{
return 0;
}
}
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
if(beginWord.empty() || endWord.empty() || wordList.empty())
{
return 0;
}
unordered_map<string , int> words;
int size = wordList.size();
for(int i = 0; i < size ; i++)
{
words[ wordList.at(i) ] = 1;
}
unordered_map<string , vector<string> > wordToNextWords;
int result = bfs(beginWord, endWord , wordList , words , wordToNextWords);
return result;
}
};
void process()
{
vector<string> nums;
string value;
int num;
Solution solution;
string beginWord;
string endWord;
vector<vector<string> > result;
while(cin >> beginWord >> endWord >> num )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
int distance = solution.ladderLength(beginWord , endWord , nums);
cout << distance << endl;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:127. Word Ladder
最新推荐文章于 2020-10-21 14:55:06 发布