方法:看到最短->bfs
难点:建图。
1:一个单词找邻居常规做法:wordList.size()word.size() 也就是5000 * 10 所有单词再 5000肯定会超时
2:如果按照单词中的每个位置进行枚举26次,然后看在wordList中是否存在:26word.size() 也就是2610 所有单词乘以5000,复杂度大大缩小,建图复杂度减小。
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
int n = wordList.size(), len = beginWord.size();
unordered_map<string, int> ump; //->下标 初始对应n
for (int i = 0; i < n; ++i) {
ump[wordList[i]] = i;
}
ump[beginWord] = n;
if (!ump.count(endWord)) return 0;
vector<vector<int>> path(n + 1);
for (int i = 0; i < len; ++i) {
string s = beginWord;
for (int j = 0; j < 26; ++j) {
//不能写成k < 26 && (s[i] != 'a' + j),不满足的话当前循环都不会执行!!!
if (s[i] == 'a' + j) continue;
s[i] = 'a' + j;
if (ump.count(s)) path[n].push_back(ump[s]);
}
}
for (int i = 0; i < n; ++i) {
int index = ump[wordList[i]];
if (path[index].size()) continue;
for (int j = 0; j < len; ++j) {
string s = wordList[i];
for (int k = 0; k < 26; ++k) {
if (s[j] == 'a' + k) continue;
s[j] = 'a' + k;
if (ump.count(s)) path[index].push_back(ump[s]);
}
}
}
vector<int> v(n + 1); //做是否入队的标记
int end = ump[endWord], layer = 1;
//layer不能出队一个就++,应该针对每一层++ !!!
queue<int> q;
q.push(n);
v[n] = true;
int nums = 1;
while (!q.empty()) {
int cnt = 0;
for (int i = 0; i < nums; ++i) {
int frt = q.front();
q.pop();
for (int j = 0; j < path[frt].size(); ++j) {
int tmp = path[frt][j];
if (!v[tmp]) {
if (tmp == end) return layer + 1;
q.push(tmp);
v[tmp] = 1;
cnt++;
}
}
}
nums = cnt;
layer++;
}
return 0;
}
};
出错的地方:
1:不能写成k < 26 && (s[i] != ‘a’ + j),不满足的话当前循环都不会执行!!!
2:layer不能出队一个就++,应该针对每一层++ !!!