刷题:BFS

BFS的过程:
1.建图:邻接矩阵(二维数组)或邻接表(多个一维数组)
2.BFS搜索框架:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=100;
bool vst[maxn][maxn]; // 访问标记
int dir[4][2]={0,1,0,-1,1,0,-1,0}; // 方向向量
struct State // BFS 队列中的状态数据结构
{
   int x,y; // 坐标位置
   int Step_Counter; // 搜索步数统计器
};
 
State a[maxn];

bool CheckState(State s) // 约束条件检验
{
   if(!vst[s.x][s.y] && ...) // 满足条件
     return 1;
   else // 约束条件冲突
    return 0;
}
  
void bfs(State st)
{
     queue <State> q; // BFS 队列
     State now,next; // 定义2 个状态,当前和下一个
     st.Step_Counter=0; // 计数器清零
     q.push(st); // 入队
     vst[st.x][st.y]=1; // 访问标记
     while(!q.empty())
     {
       now=q.front(); // 取队首元素进行扩展
       if(now==G) // 出现目标态,此时为Step_Counter 的最小值
       {
         ...... 
        return;
       }
       for(int i=0 ; i<4 ; i++)
       {
         next.x=now.x+dir[i][0]; // 按照规则生成下一个状态
         next.y=now.y+dir[i][1];
         next.Step_Counter=now.Step_Counter+1; // 计数器加1
         if(CheckState(next)) // 如果状态满足约束条件则入队
          {
          q.push(next);
          vst[next.x][next.y]=1; //访问标记
          }
       }
     q.pop(); // 队首元素出队
  }
 return;
}

题目:
1.LeetCode101
思路:
一次取出两个数;
注意:
1).先判断是否为NULL,再判断val是否相等
代码:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        queue<TreeNode*> q ;
        if(root == NULL) return true ;
        q.push(root) ;
        q.push(root) ;
        while(!q.empty()) {
            TreeNode* u1 = q.front() ;
            q.pop() ;
            TreeNode* u2 = q.front() ;
            q.pop() ;     
            if(u1 == NULL && u2 == NULL) continue ;
            if(u1 == NULL || u2 == NULL) return false ;
            if(u1->val != u2->val) return false ;
            q.push(u1->left) ;
            q.push(u2->right) ;
            q.push(u1->right) ;
            q.push(u2->left) ;
        }
        return true ;
    }
};

2.LeetCode103
思路:
for出每层,偶数层reverse
注意:
1).int q_length = q.size();for(int i = 0 ; i < q_length ; i ++ )
for(int i = 0 ; i < q.size() ; i ++ )
2).if(root == NULL) return ans ;
代码:

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> ans ;
        queue<TreeNode*> q ;
        if(root == NULL) return ans ;
        q.push(root) ;
        int cnt = 0 ;
        while(!q.empty()) {
            int size = q.size() ;
            vector<int> ans0 ;
            for(int i = 0 ; i < size ; i ++) {
                TreeNode* u = q.front() ;
                q.pop() ;
                ans0.push_back(u->val) ;
                if(u->left) q.push(u->left) ;
                if(u->right) q.push(u->right) ;
            }
            if(cnt%2 == 1) reverse(ans0.begin() , ans0.end()) ;
            ans.push_back(ans0) ;
            cnt ++ ;
        }
        return ans ;
    }
};

3.LeetCode111
代码:

class Solution {
public:
    int minDepth(TreeNode* root) {
        queue<TreeNode*> q ;
        if(!root) return 0 ;
        q.push(root) ;
        int deep = 1 ;
        while(!q.empty()) {
            int size = q.size() ;
            for( ; size > 0 ; size --) {
                TreeNode* u = q.front() ;
                q.pop() ;
                if(!u->left && !u->right) return deep ;
                if(u->left) q.push(u->left) ;
                if(u->right) q.push(u->right) ;
            }
            deep ++ ;
        }
        return deep ;
    }
};

4.LeetCode199
代码:

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> q ;
        vector<int> ans ;
        if(root == NULL) return ans ;
        q.push(root) ;
        while(!q.empty()) {
            int size = q.size() ;
            for(int i = 0 ; i < size ; i ++) {
                TreeNode* u = q.front() ;
                q.pop() ;
                if(i == 0) ans.push_back(u->val) ;
                if(u->right) q.push(u->right) ;
                if(u->left) q.push(u->left) ;
            }
        }
        return ans ;
    }
};

5.LeetCode207(拓扑排序)
注意:
1).vector<vector<int>> graph(numCourses , vector<int>(numCourses)) ;错 ;
vector<vector<int>> graph(numCourses) ;对 ;
为啥?上面的那个规定了graph[i]的长度,但它可能没那么长,但是之后把graph[i]全遍历了一遍;
代码:

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<int> degree(numCourses) ;
        vector<vector<int>> graph(numCourses) ;
        queue<int> q ;
        if(prerequisites.size() == 0) return true ;
        for(int i = 0 ; i < prerequisites.size() ; i ++) {
            graph[prerequisites[i][1]].push_back(prerequisites[i][0]) ;
            degree[prerequisites[i][0]] ++ ;
        }
        for(int i = 0 ; i < numCourses ; i ++) {
            if(degree[i] == 0) q.push(i) ;
        }
        int cnt = 0 ;
        while(!q.empty()) {
            int temp = q.front() ;
            q.pop() ;
            cnt ++ ;
            for(int i = 0 ; i < graph[temp].size() ; i ++) {
                degree[graph[temp][i]] -- ;
                if(degree[graph[temp][i]] == 0) q.push(graph[temp][i]) ;
            }
        }
        return cnt == numCourses ;
    }
};

6.LeetCode310(拓扑排序)
思路:
和上面那道题比较像,但是这道题是无序图,所以上面那道题需要入度表和出度对应表,但这道题不分出入度。从外层一层一层拨;
代码:

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        vector<int> degree(n , 0) ;
        vector<vector<int>> graph(n) ;
        queue<int> q ;
        vector<int> ans ;
        for(int i = 0 ; i < edges.size() ; i ++) {
            graph[edges[i][0]].push_back(edges[i][1]) ;
            graph[edges[i][1]].push_back(edges[i][0]) ;
            degree[edges[i][0]] ++ ;
            degree[edges[i][1]] ++ ;
        }
        int res = n ;
        if(res == 1) ans.push_back(0) ;
        for(int i = 0 ; i < n ; i ++) {
            if(degree[i] == 1) q.push(i) ;
        }
        while(res != 1 && res != 2) {
            int size = q.size() ;
            res -= size ;
            for(int i = 0 ; i < size ; i ++) {
                int temp = q.front() ;
                q.pop() ;
                for(int j = 0 ; j < graph[temp].size() ; j ++) {
                    if(degree[graph[temp][j]] > 0) degree[graph[temp][j]] -- ;
                    if(degree[graph[temp][j]] == 1) q.push(graph[temp][j]) ; 
                }
            }
        }
        while(!q.empty()) {
            ans.push_back(q.front()) ;
            q.pop() ;
        }
        return ans ;
    }
};

7.LeetCode127
思路:
双向bfs,每次只挑短的那个遍历
代码:

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> dict(wordList.begin() , wordList.end()) ;
        unordered_set<string> beginset , endset , tmp , visited ;
        if(dict.find(endWord) == dict.end()) return 0 ;
        beginset.insert(beginWord) ;
        endset.insert(endWord) ;
        int len = 1 ;
        while(!beginset.empty() && !endset.empty()) {
            if(beginset.size() > endset.size()) {
                tmp = beginset ;
                beginset = endset ;
                endset = tmp ;
            }
            tmp.clear() ;
            for(auto word : beginset) {
                for(int i = 0 ; i <word.size() ; i ++) {
                    char old = word[i] ;
                    for(char c = 'a' ; c <= 'z' ; c ++) {
                        word[i] = c ;
                        if(c == old) continue ;
                        else {
                            if(endset.find(word) != endset.end()) return len + 1 ;
                            if(visited.find(word) == visited.end() && dict.find(word) != dict.end()) {
                                tmp.insert(word) ;
                                visited.insert(word) ;
                            }
                        }
                    }
                    word[i] = old ;
                }
            }
            beginset = tmp ;
            len ++ ;
        }
        return 0 ;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值