Leetcode 01矩阵 逆向思维

题目

Leetcode 01矩阵

打卡打卡打卡~

给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。

两个相邻元素间的距离为 1 。

示例 1:
输入:

0 0 0
0 1 0
0 0 0

输出:

0 0 0
0 1 0
0 0 0

示例 2:
输入:

0 0 0
0 1 0
1 1 1

输出:

0 0 0
0 1 0
1 2 1

注意:

  1. 给定矩阵的元素个数不超过 10000。
  2. 给定矩阵中至少有一个元素是 0。
  3. 矩阵中的元素只在四个方向上相邻: 上、下、左、右。

思路

  • 广度优先搜索

    找最短,最近距离先想到的应该是广搜。这里找1到0的最近距离,那么第一个思路是遍历所有的1,从1开始bfs找最近的0。这样的思路很容易想到,不过时间复杂度很高。

    那么可以换个思维,思维很重要!!!如果1到0的路径构成最短距离,那反过来0到1的路径也能构成最短距离。所以把0作为源点开始遍历整个矩阵。题目还有一个关键点是矩阵中可能有多个0,那么多个0要怎么处理。

    多个0的话,我们可以构造一个多源点的BFS树,这样遍历,最后的距离也是最优的。

代码

class Solution {
public:
    int mv[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        // 标记数组
        vector<vector<int>> flag(m, vector<int>(n));
        // BFS队列
        queue<pair<int, int>> que;
        int step = 0;
        // 遍历每个点,因为零是比较少的点,适合做bfs的根节点
        for (int i = 0; i < m; i++) { // y
            for (int j = 0; j < n; j++) { // x
                if (matrix[i][j] == 0) {
                    que.emplace(j, i); // (x, y)
                    flag[i][j] = 1;
                }
            }
        }
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                auto [x, y] = que.front();
                que.pop();
                for (int j = 0; j < 4; j++) {
                    int dx = x + mv[j][0];
                    int dy = y + mv[j][1];
                    if (dx >= 0 && dx < n && dy >= 0 && dy < m && !flag[dy][dx]) {
                        que.emplace(dx, dy);
                        matrix[dy][dx] = step + 1;
                        flag[dy][dx] = 1;
                    }
                }
            }
            step++;
        }
        return matrix;
    }
};

你可能感兴趣的:(算法)