LeeCode 126 bfs

题意

传送门 LeeCode 126. 单词接龙 II

题解

求从 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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值