剑指offer专项突击版第36天

这篇博客探讨了三种基于图遍历的算法在信息技术问题中的应用。首先,介绍了用于计算岛屿最大面积的深度优先搜索(DFS)策略,强调了在处理过程中避免错误计数的关键点。接着,讲解了如何通过DFS判断二分图,通过为节点染色来确保没有相邻节点拥有相同颜色。最后,展示了如何利用广度优先搜索(BFS)求解矩阵中元素间的最短距离,利用BFS的特性保证了找到的路径是最短的。这些算法在解决实际问题时具有重要的实践价值。

剑指 Offer II 105. 岛屿的最大面积

简单的图遍历(可dfs,也可bfs),这里给出dfs。这里有个坑点:不能直接将个数传到下个栈帧然后用全局变量直接取值,虽然都会遍历到,但是计算的个数会被刷新变少,所以我这里直接让每个栈帧都分别返回它所找到1最后拼凑个数。

class Solution {
public:
    int n, m;
    int ne[4][2] = {{-1,0},{0,-1},{1,0},{0,1}}; //上左下右
    bool st[55][55] = {0};
    int dfs(vector<vector<int>> &grid, int x, int y) {
        st[x][y] = true;
        int cnt = 1;
        for(int i = 0; i < 4; i++) {
            int tx = x + ne[i][0];
            int ty = y + ne[i][1];
            if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
            if(grid[tx][ty] && !st[tx][ty]) {
                cnt += dfs(grid,tx,ty);
            }        
        }
        return cnt;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        n = grid.size(), m = grid[0].size();
        int res = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++) 
                if(grid[i][j] && !st[i][j]) 
                    res = max(res, dfs(grid,i,j));
        return res;
    }
};

剑指 Offer II 106. 二分图

  • 二分图补充:A、B子集中的每个结点分别都互不相连。
  • c o l o r color color :0表示未染色,1、2用来区分所染颜色。
  • 由与题目给的图不一定是连通图,所以为了避免漏掉遍历的结点,故轮询一遍每个结点。
  • 当相邻的点染为相同的颜色时,就说明染色失败,这个测试点就不是二分图,直接返回false即可。
  • 3 − c 3-c 3c 比较妙,当 c c c 为 1 时就返回 2 , c c c 为 2 时返回 1 ,刚好是相反的颜色。
class Solution {
public:
    vector<int> color;
    bool dfs(int u, int c, vector<vector<int>> &graph) {
        color[u] = c;
        for(const auto &v: graph[u]) {
            if(!color[v]) {
                if(!dfs(v,3-c,graph)) return false; //上个栈帧染色失败
            } else if(color[v] == c) return false; //染相同颜色
        }
        return true; 
    }
    bool isBipartite(vector<vector<int>>& graph) {
        int n = graph.size();
        color.resize(n);
        for(int i = 0; i < n; i++) //轮询每个结点,以防非连通图
            for(const auto &v: graph[i]) {
                if(!color[v] && !dfs(v,1,graph)) return false;
            }
        return true;    
    }
};

剑指 Offer II 107. 矩阵中的距离

广度优先(BFS)

  1. 使用 d f s dfs dfs 不好优化成记忆搜索,这里使用 B F S BFS BFS 会相对容易一些。
  2. 直接将所有 0 0 0 的点标记为访问过,并且都加入队列中。
  3. 然后开始 B F S BFS BFS ,那么理所当然的 0 0 0 的点都不会被再次加入队列。
  4. 由于 B F S BFS BFS 自带的最短步数特性,此时 1 1 1 的点等于上个点的步数+1一定是最短的。
  5. 然后再将 1 1 1 加入队列以此类推,直至所有点均访问完毕。
class Solution {
public:
    int ne[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
    typedef pair<int,int> PII; 
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
        int n = mat.size(), m = mat[0].size();
        vector<vector<int>> dis(n, vector<int>(m,0));
        vector<vector<bool>> st(n,vector<bool>(m,0));
        queue<PII> que;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                if(mat[i][j] == 0) {
                    que.emplace(i,j);
                    st[i][j] = true;
                }

        while(que.size()) {
            auto [x,y] = que.front(); que.pop();
            for(int i = 0; i < 4; i++) {
                int tx = x + ne[i][0];
                int ty = y + ne[i][1];
                if(tx < 0 || tx >= n || ty < 0 || ty >= m || st[tx][ty]) continue;
                dis[tx][ty] = dis[x][y] + 1;
                st[tx][ty] = true;
                que.emplace(tx,ty);
            }
        }

        return dis;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值