543.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.广度优先搜索,对于每一个1节点来说,要找距离最近的点,先找出上下左右四个方向的点,加入队列中。

对于队列中的每个元素,判断是否为零,为零则结束搜索,设置距离。不为零就将其周围的点加入到队列中。

Code:

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        
     
        int m=matrix.size();
        int n = matrix[0].size();
      vector<vector<int> >dp(m,vector<int>(n,5));
     pair<int,int>index;
     bool flag=false;;
      for(int i=0;i<=m;i++)
        for(int j=0;j<=n;j++)
        {
          queue< pair<int,int> >que;
          flag=false;int dep=0;
            que.push(make_pair(i,j));
            while(!que.empty()){
                    if(flag)break;
                int num=que.size();
               while(num--)
                {
                index=que.front();
                que.pop();
                int row=index.first;
                int col=index.second;
                if(row<0||row>=m||col<0||col>=n)continue;
                if(matrix[row][col]==0){dp[i][j]=dep;flag=true;break;}
                  else{  que.push(make_pair(row-1,col));
                    que.push(make_pair(row+1,col));
                    que.push(make_pair(row,col-1));
                    que.push(make_pair(row,col+1));
                    }
                }
                dep++;
            }
        }
        return dp;
    }
};

思路二:

我们首先建立一个和matrix大小相等的矩阵res,初始化为很大的值,这里我们用INT_MAX-1,为甚么要减1呢,后面再说。然后我们遍历matrix矩阵,当遇到为0的位置,我们将结果res矩阵的对应位置也设为0,这make sense吧,就不多说了。然后就是这个解法的精髓了,如果不是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 n = matrix.size(), m = matrix[0].size();
        vector<vector<int> >ans(n, vector<int>(m, INT_MAX-1));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(matrix[i][j] == 0)
                    ans[i][j] = 0;
                else
                {
                    ans[i][j] = min(ans[i][j], ans[i][max(0,j-1)]+1);
                    ans[i][j] = min(ans[i][j], ans[max(0,i-1)][j]+1);
                }
            }
        }
        for(int i=n-1;i>=0;i--)
        {
            for(int j=m-1;j>=0;j--)
            {
                if(matrix[i][j] == 0)
                    ans[i][j] = 0;
                else
                {
                    ans[i][j] = min(ans[i][j], ans[min(i+1, n-1)][j]+1);
                    ans[i][j] = min(ans[i][j], ans[i][min(j+1, m-1)]+1);
                }
            }
            
        }
        return ans;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值