回溯3-----BFS(一石激起千层浪)

广度优先搜索

需要借助 队列 来解决问题
例如二叉树的层序遍历 :
1, 将根节点入队
2, 队列出队的时候, 将该节点的左右子树节点入队, 然后循环操作。 这就是广度优先搜索。

力扣429-----N叉树的层序遍历

力扣429
在这里插入图片描述

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root)
    {
        if (root == nullptr)
            return vector<vector<int>>();

        vector<vector<int>> vv;
        queue<Node*> q;
        q.push(root);

        while (!q.empty())
        {
            vector<int> v;
            int sz = q.size();
            while (sz--)
            {
                Node* node = q.front();
                q.pop();

                v.push_back(node->val);
                for (auto e : node->children)
                {
                    q.push(e);
                }
            }

            vv.push_back(v);
        }

        return vv;
    }
};

力扣994-----腐烂的橘子

力扣题994
1,解题思路 : BFS。
2,把第一次腐烂的橘子入队,(注意:这一次腐烂的橘子不计次数, 所以step不用计步数),然后取出每一个橘子,
向四周渲染(腐烂), 如果四周是好的橘子,就要将该位置的橘子改为2, 然后加入队列中。
然后循环上述的步骤就可以
在这里插入图片描述

int arr[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) 
    {
        //1,找到一个腐烂的橘子
        queue<pair<int,int>> q;
        bool flag = false;
        for(int i = 0; i < grid.size(); i++)
        {
            for(int j = 0; j < grid[0].size(); j++)
            {
                if(grid[i][j] == 2)
                {
                     q.push({i, j});
                }

                if(grid[i][j] == 1)
                {
                    flag = true;
                }
            }
        }

        if(flag == false)
                return 0;
        
        int step = 0;
        while(!q.empty())
        {
            int sz = q.size();
            while(sz--)
            {
               auto front = q.front();
               q.pop();

               for(int i = 0; i < 4; i++)
               {
                   int newx = arr[i][0] + front.first;
                   int newy = arr[i][1] + front.second;
                   
                   if(newx < 0 || newx >= grid.size()
                   || newy < 0 || newy >= grid[0].size())
                         continue;
                   
                   if(grid[newx][newy] == 1)
                   {
                       grid[newx][newy] = 2;
                       q.push({newx, newy});
                   }
               }  
            }
            step++;
        }
        
         for(int i = 0; i < grid.size(); i++)
        {
            for(int j = 0; j < grid[0].size(); j++)
            {
                if(grid[i][j] == 1)
                {
                     return -1;
                }
            }
        }


        return step - 1;
    }
};

力扣127 -------单词接龙

力扣127
首先,将beginword入队。
然后 将beginword转换后的全部字符
判断是不是在字典wordlist中,如果在就可以入队,
但是wordlist中的字符串只能用一次, 否则会无脑循环。

然后将一次性入队字符串再进行上次的循环操作就可以
在这里插入图片描述

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) 
    {
         unordered_map<string, bool> m; //标识字符串是否用过了
         for(auto& e : wordList)
            m[e] = true;
        
         if(m.find(endWord) == m.end())
                return 0;
         
         int step = 0;
         queue<string> q;
         q.push(beginWord);

         while(!q.empty())
         {
             int sz = q.size();
             step++;
             while(sz--)
             {
                 string str = q.front();
                 q.pop();
                 
                 if(str == endWord)
                      return step;

                 for(int i = 0; i < str.size(); i++)
                 {
                       string s = str;
                       for(char ch = 'a'; ch <= 'z'; ch++)
                       {
                           s[i] = ch;

                           if(m[s] == true)
                           {
                               q.push(s);
                               m[s] = false;
                           }
                       }
                 }
             }
         }
         
         return 0;
    }
};

类似的题目:
力扣433

class Solution {
public:
    int minMutation(string startGene, string endGene, vector<string>& bank) 
    {
        unordered_map<string, bool> m;
        for(auto& e : bank)
              m[e] = true;

        if(m.find(endGene) == m.end())
            return -1;

        int step = 0;
        queue<string> q;
        q.push(startGene);
        string gene = "ACGT";

        while(!q.empty())
        {
            int sz = q.size();
            step++;
            while(sz--)
            {
                string str = q.front();
                q.pop();
                
                if(str == endGene)
                    return step - 1;

                for(int i = 0; i < str.size(); i++)
                {
                    string s = str;
                    for(int j = 0; j < gene.size(); j++)
                    {
                        s[i] = gene[j];

                        if(m[s] == true)
                        {
                            q.push(s);
                            m[s] = false;
                        }
                    }
                }
            }
        }

        return -1;      
    }
};

力扣725------打开转盘锁

力扣725

解题思路非常清晰 : BFS
但是要用一个set 来标记这个字符串是否用过, 用过了就不能用了。

循环:
1, 取出队列中的一个元素。
2, 将每个元素的旋转的所有可能性全部入队 (不能出现在死亡数字里面)

在这里插入图片描述

class Solution {
public:
    int openLock(vector<string>& deadends, string target) 
    {
       unordered_map<string, bool> m;
       set<string> _set;

       for(auto& e : deadends)
           m[e] = true;
       
       if(m["0000"] == true || m[target] == true)
            return -1;

       queue<string> q;
       q.push("0000");
       int step = 0;
       
       while(!q.empty())
       {
           int sz = q.size();
           step++;
     
           while(sz--)
           {
               string str = q.front();
               q.pop();
                
               if(str == target)
                   return step - 1;

               for(int i = 0; i < 4; i++)
               {
                   string s1 = str;
                   if(s1[i] == '9')
                          s1[i] = '0';
                   else
                      s1[i]++;
                   
                   string s2 = str;
                   if(s2[i] == '0')
                        s2[i] = '9';
                   else
                      s2[i]--;

                   if(m[s1] != true && _set.find(s1) == _set.end())
                   {
                      q.push(s1);
                      _set.insert(s1);
                   }

                   if(m[s2] != true && _set.find(s2) == _set.end())
                   {
                      q.push(s2);
                      _set.insert(s2);
                   }
               }
           }
       }
       
       return -1;
    }
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

通过全部用例

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值