把本题抽象为图模型:节点为length(length为start的长度)位个字母(每个字母有26种可能)的排列组合;若一个节点A通过改变一个字母变化到另外一个节点B(B节点在dict中),则有一条边A--B;否则两节点间没有边。此题可抽象为已知起点和终点,是否可以找到一条最短路径L,使得通过L,可以从起点到达终点。可以使用BFS来解。
#include <iostream>
#include <unordered_set>//mac os下引用unordered_set,散列容器
#include <string>
#include <queue>
using namespace std;
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if (start==end) {
return 1;
}
queue<string> nodes;//使用queue容器
queue<int> depth;
nodes.push(start);//start入队列
depth.push(1);//1入队
findItem(start, dict);//查看是否存在于字典中
while (nodes.size()>0) {//遍历每一个单词
string cur=nodes.front();//访问队首元素
nodes.pop();//队列的第一个元素出队列
int dep=depth.front();//步数初始为1
depth.pop();
for (int i=0; i<cur.size(); i++) {//改变单词的字母
for (int j=0; j<26; j++) {//26个英文字母
if (cur[i]!='a'+j) {
string temp=cur;
temp[i]='a'+j;
if (temp==end) {
return dep+1;//可以转换为end,需要dep+1步
}
if (findItem(temp, dict)) {
nodes.push(temp);
depth.push(dep+1);
}
}
}
}
}
return 0;
}
bool findItem(string ts,unordered_set<string> &dict){
//const_iterator:常数的迭代器类型的控制序列的
//find:查找与指定键匹配的元素
unordered_set<string>::const_iterator ci=dict.find(ts);
if (ci!=dict.end()) {//找到了
dict.erase(ci);//移除指定位置处的元素
return true;
}else{
return false;//没找到
}
return true;
}
};
int main(){
string start = "hit";
string end = "cog";
unordered_set<string> dict = {"hot","dot","dog","lot","log"};
Solution so;
int res=so.ladderLength(start, end, dict);
cout<<res<<endl;
return 0;
}
Solution2
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if (start==end) {
return 1;
}
queue<string> nodes;
nodes.push(start);
queue<int> depth;
depth.push(1);
findItem(start, dict);
while (!nodes.empty()) {
string cur=nodes.front();
nodes.pop();
int dep=depth.front();
depth.pop();
for (int i=0; i<cur.size(); i++) {
for (int j=0; j<26; j++) {
string temp=cur;
if (temp[i]!='a'+j) {
temp[i]='a'+j;
if (temp==end) {
return dep+1;
}
if (findItem(temp, dict)) {
nodes.push(temp);
depth.push(dep+1);
}
}
}
}
}
return 0;
}
bool findItem(string target,unordered_set<string> &dict){
unordered_set<string>::const_iterator ci= dict.find(target);
if (ci!=dict.end()) {
dict.erase(ci);
return true;
}else{
return false;
}
}
};