Problem description
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.
- UPDATE (2017/1/20): The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
Solution
递归法(暴力搜索):
#include <iostream>
#include <string>
#include <assert.h>
#include <vector>
using namespace std;
bool *isDealed;
bool isOneCharDiff(string s1, string s2)
{
assert(s1.length() == s2.length());
int cnt = 0;
for (int i = 0; i < s1.length(); i++)
{
if (s1[i] != s2[i])
cnt++;
}
if (cnt != 1)
return false;
return true;
}
void wordLadder(string beginWord, vector<string> &WordList, string endWord, int n, int depth, int *pL)
{
if (beginWord == endWord)
{
if (*pL > depth)
*pL = depth;
return;
}
if (depth == n)
return;
for (int i = 0; i < n; i++)
{
if (!isDealed[i] && isOneCharDiff(WordList[i], beginWord))
{
isDealed[i] = true;
wordLadder(WordList[i], WordList, endWord, n, depth + 1, pL);
isDealed[i] = false;
}
}
}
int main()
{
string beginWord, endWord;
int n;
cin >> beginWord >> endWord >> n;
isDealed = new bool[n];
vector<string> WordList(n);
for (int i = 0; i < n; i++)
{
cin >> WordList[i];
isDealed[i] = false;
}
int L = n + 1;
wordLadder(beginWord, WordList, endWord, n, 0, &L);
if (L < n + 1)
cout << L << endl;
else
cout << 0 << endl;
delete[] isDealed;
return 0;
}
BFS法
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <queue>
using namespace std;
// one end bfs
/*class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { set<string> wordSet(wordList.begin(), wordList.end()); char tmp; queue<string> Q; Q.push(beginWord); Q.push(""); //以空作为每一层的结束 int res = 1; while(!Q.empty()) { string str = Q.front(); Q.pop(); if (str != "") { for(int i = 0; i < str.length(); i++) { tmp = str[i]; for (char c = 'a'; c <= 'z'; c++) { if(str[i] == c) continue; str[i] = c; set<string>::iterator idx = wordSet.find(str); //vector<string>::iterator idx = find(wordList.begin(), wordList.end(), str); if (idx != wordSet.end()) { if (str == endWord) return res + 1; Q.push(str); wordSet.erase(idx); } } str[i] = tmp; } } else if (!Q.empty()) { res++; Q.push(""); } } return 0; } }; */
// two end bfs
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
set<string> wordSet(wordList.begin(), wordList.end());
set<string> beginSet, endSet, *set1, *set2;
beginSet.insert(beginWord);
endSet.insert(endWord);
int res = 1;
if (wordSet.find(endWord) == wordSet.end())
return 0;
while (!beginSet.empty() && !endSet.empty())
{
if (beginSet.size() <= endSet.size())
{
set1 = &beginSet;
set2 = &endSet;
}
else
{
set1 = &endSet;
set2 = &beginSet;
}
set<string> itemSet;
set<string>::iterator i;
for (i = set1->begin(); i != set1->end(); i++)
{
string str = *i;
for (int i = 0; i < str.length(); i++)
{
char tmp = str[i];
for (char c = 'a'; c <= 'z'; c++)
{
if (str[i] == c) continue;
str[i] = c;
set<string>::iterator j = set2->find(str);
if (j != set2->end())
return res + 1;
set<string>::iterator idx = wordSet.find(str);
if (idx != wordSet.end())
{
itemSet.insert(str);
wordSet.erase(idx);
}
}
str[i] = tmp;
}
}
swap(*set1, itemSet);
res++;
}
return 0;
}
};
int main()
{
string str_array[] ={"hot","dot","dog","lot","log","cog"}; //以这个序列为例
string begin = "hit";
string end = "cog";
vector<string> wordList(str_array, str_array + 6);
Solution s;
cout << s.ladderLength(begin, end, wordList) << endl;
return 0;
}
link: