LeetCode日常刷题542

542. 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. 矩阵中的元素只在四个方向上相邻: 上、下、左、右。

BFS方法,执行时间为304ms

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}};
        queue<pair<int, int>> q;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) q.push({i, j});
                else matrix[i][j] = INT_MAX;
            }
        }
        while (!q.empty()) {
            auto t = q.front(); q.pop();
            for (auto dir : dirs) {
                int x = t.first + dir[0], y = t.second + dir[1];
                if (x < 0 || x >= m || y < 0 || y >= n ||
                matrix[x][y] <= matrix[t.first][t.second]) continue;
                matrix[x][y] = matrix[t.first][t.second] + 1;
                q.push({x, y});
            }
        }
        return matrix;
    }
};

执行时间为196ms

二次扫描的解法,从而不用使用BFS了。这种解法也相当的巧妙,首先建立一个和matrix大小相等的矩阵res,初始化为很大的值,这里我们用INT_MAX-1。然后遍历matrix矩阵,当遇到为0的位置,将结果res矩阵的对应位置也设为0。这个解法的精髓,如果不是0的地方,在第一次扫描的时候,比较其左边和上边的位置,取其中较小的值,再加上1,来更新结果res中的对应位置。这里就明白了为啥要初始化为INT_MAX-1了,因为这里要加1,如果初始化为INT_MAX就会整型溢出,不过,由于是取较小值,res[i][j]永远不会取到INT_MAX,所以不会有再加1溢出的风险。第一次遍历比较了左和上的方向,那么我们第二次遍历就要比较右和下的方向,注意两种情况下不需要比较,一种是当值为0时,还有一种是当值为1时,这两种情况下值都不可能再变小了,所以没有更新的必要,参见代码如下:

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        vector<vector<int>> res(m, vector<int>(n, INT_MAX - 1));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) res[i][j] = 0;
                else {
                    if (i > 0) res[i][j] = min(res[i][j], res[i - 1][j] + 1);
                    if (j > 0) res[i][j] = min(res[i][j], res[i][j - 1] + 1);
                }
            }
        }
        for (int i = m - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                if (res[i][j] != 0 && res[i][j] != 1) {
                    if (i < m - 1) res[i][j] = min(res[i][j], res[i + 1][j] + 1);
                    if (j < n - 1) res[i][j] = min(res[i][j], res[i][j + 1] + 1);
                }
            }
        }
        return res;
    }
};

用时172ms的解法:

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        vector<vector<int>>result;
        int m=matrix.size();
        if(m==0)
            return result;
        int n=matrix[0].size();
        result=vector<vector<int>>(m,vector<int>(n,n*m+1));
        for(int i=0;i<n;++i)
        {
            if(matrix[0][i]==0)
                result[0][i]=0;
            for(int j=1;j<m;++j)
            {
                if(matrix[j][i]==0)
                    result[j][i]=0;
                result[j][i]=min(result[j][i],1+result[j-1][i]);
            }
        }
        for(int i=0;i<n;++i)
        {
            if(matrix[m-1][i]==0)
                result[m-1][i]=0;
            for(int j=m-2;j>=0;--j)
            {
                if(matrix[j][i]==0)
                    result[j][i]=0;
                result[j][i]=min(result[j][i],1+result[j+1][i]);
            }
        }
        for(int i=0;i<m;++i)
        {
            if(matrix[i][0]==0)
                result[i][0]=0;
            for(int j=1;j<n;++j)
            {
                if(matrix[i][j]==0)
                    result[i][j]=0;
                result[i][j]=min(result[i][j],1+result[i][j-1]);
            }
        }
        for(int i=0;i<m;++i)
        {
            if(matrix[i][n-1]==0)
                result[i][n-1]=0;
            for(int j=n-2;j>=0;--j)
            {
                if(matrix[i][j]==0)
                    result[i][j]=0;
                result[i][j]=min(result[i][j],1+result[i][j+1]);
            }
        }
        return result;
    }
};

猜你喜欢

转载自blog.csdn.net/zhang_yixuan_ss/article/details/80336002