leetcode127. 单词接龙 双向BFS

双向BFS(Bidirectional Breadth-First Search)是一种图搜索算法,它从图的两端同时开始搜索,直到两个搜索相遇。其基本思想是从起始点和目标点同时进行BFS搜索,直到两个搜索相遇为止,这个相遇的点就是起始点和目标点之间的最短路径。

双向BFS的搜索过程如下:

  1. 初始化起始点和目标点,将它们分别放入起点队列和目标点队列中。

  2. 从起点队列和目标点队列中分别取出一个点,分别进行扩展操作。比如,从起点队列中取出一个点,遍历它的所有邻居节点,将未被访问的邻居节点加入到起点队列中,并记录它们的深度(或距离)。

  3. 同样地,从目标点队列中取出一个点,遍历它的所有邻居节点,将未被访问的邻居节点加入到目标点队列中,并记录它们的深度(或距离)。

  4. 检查起点队列和目标点队列中的节点是否相遇。如果相遇,说明已经找到了起点和目标点之间的最短路径。此时可以停止搜索并返回最短路径。

  5. 如果起点队列和目标点队列中的节点没有相遇,继续从两个队列中取出节点进行扩展操作,直到相遇为止。

双向BFS通常可以比传统的BFS更快地找到最短路径,因为它可以同时从起点和目标点进行搜索,从而减少搜索空间。同时,双向BFS还需要使用两个队列来存储搜索过程中的节点,因此需要更多的空间。

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
    //预处理
    if(find(wordList.begin(),wordList.end(),endWord)==wordList.end())
        return 0;
    if(find(wordList.begin(),wordList.end(),beginWord)==wordList.end())
        wordList.push_back(beginWord);

    queue<string>bq,eq;
    unordered_set<string>check1,check2;
    int n1=1,n2=1;//记录搜索层数
    check1.insert(beginWord);
    check2.insert(endWord);
    bq.push(beginWord);
    eq.push(endWord);
    while(!bq.empty()&&!eq.empty())
    {
        if(bq.size()>eq.size())//交替bfs
        {
            if(bfs(eq,check2,check1,wordList))
                return n1+n2;
            n2++;
        }
        else
        {
            if(bfs(bq,check1,check2,wordList))
                return n1+n2;
            n1++;
        }
    }
    return 0;
    }

    //遍历一层
    bool bfs(queue<string>&q,unordered_set<string>&q_check,unordered_set<string>&t_check,vector<string>&wordList)
    	//q表示要bfs的队列,q_check表示改队列对应的哈希,t_check表示相反方向的bfs对应的哈希
    {
        int sum=q.size();
        while(sum--)
        {
            for(auto &a:wordList)// 遍历词典
            {
               if(q_check.find(a)!=q_check.end()) //如果访问过
                    continue;
                if(ifturn(q.front(),a)) // 如果能转化
                {
                    if(t_check.find(a)!=t_check.end()) // 如果另一侧已经访问过了
                        return true;
                    else
                        {
                            q.push(a);//将q.front()的邻接点入栈
                            q_check.insert(a);
                        }
                }
            }
            q.pop();
        }
        return false;
    }
    bool ifturn(string&a,string&b)//判断能否转化
    {
        int dif=0;
        for(int i=0;i<a.size();i++)
        {
            if(a[i]!=b[i])
                dif++;
        }
        return dif==1;
    }
};

CG

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值