题意
题解
求从 b e g i n W o r d beginWord beginWord 到 e n d W o r d endWord endWord 的最短转换序列。将单词看做点,对仅有一个字母差异(即可以直接相互转换)的点连边。建图后 b f s bfs bfs 求解。
需要输出所有最短序列,所以判断是否将当前点插入队列的条件,除了这个点未遍历过,还要考虑它与起点的距离是否刚好被前驱节点更新。对所有节点与起点距离初始化为 i n f inf inf,设前驱节点为 i ′ i' i′,当前节点为 i i i,则将当前点插入队列的条件为
( d e p [ i ] = i n f ) ∣ ∣ ( d e p [ i ] = d e p [ i ′ ] + 1 ) (dep[i]=inf)\ ||\ (dep[i]=dep[i']+1) (dep[i]=inf) ∣∣ (dep[i]=dep[i′]+1)
class Solution
{
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList)
{
if (wordList.size() == 0)
return {};
bool fb = 0, fe = 0;
wordList.push_back(beginWord);
int n = wordList.size(), len = wordList[0].length();
int s, t;
vector<vector<int>> G(n);
for (int i = 0; i < n; i++)
{
if (!fb && wordList[i] == beginWord)
{
fb = 1;
s = i;
}
if (!fe && wordList[i] == endWord)
{
fe = 1;
t = i;
}
for (int j = i + 1; j < n; j++)
{
int dif = 0;
for (int k = 0; k < len; k++)
{
if (wordList[i][k] == wordList[j][k])
continue;
if (++dif > 1)
break;
}
if (dif == 1)
{
G[i].push_back(j);
G[j].push_back(i);
}
}
}
if (!fe)
return {};
int mincost = INT_MAX;
vector<vector<string>> res;
vector<int> dep(n, INT_MAX);
queue<vector<int>> que;
que.push(vector<int>(1, s));
dep[s] = 0;
while (!que.empty())
{
vector<int> tmp = que.front();
que.pop();
if (tmp.size() > mincost)
break;
int v = tmp.back();
if (v == t)
{
mincost = tmp.size();
vector<string> s(mincost);
for (int i = 0; i < mincost; i++)
{
s[i] = wordList[tmp[i]];
}
res.push_back(s);
continue;
}
for (int i = 0; i < G[v].size(); i++)
{
int u = G[v][i];
if (dep[u] == INT_MAX || dep[u] == dep[v] + 1)
{
vector<int> tmp2 = tmp;
tmp2.push_back(u);
que.push(tmp2);
dep[u] = dep[v] + 1;
}
}
}
return res;
}
};