0
点赞
收藏
分享

微信扫一扫

Leetcode——542. 01 矩阵

生态人 2022-04-14 阅读 97

概述

题目链接

  • 题目没有需要注意的地方

分析

BFS

因为要求最近距离考虑使用BFS

动态规划

dp[i][j]:mat[i][j]离0最近的距离
d p [ i ] [ j ] = { 1 + m i n ( d p [ i + 1 ] [ j ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j + 1 ] , d p [ i ] [ j − 1 ] ) , if mat[i][j] = 1 0 if mat[i][j] = 0 dp[i][j] = \begin{cases} 1 + min(dp[i+1][j], dp[i-1][j], dp[i][j+1],dp[i][j-1]), &\text{if mat[i][j] = 1} \\ 0 &\text{if mat[i][j] = 0} \end{cases} dp[i][j]={1+min(dp[i+1][j],dp[i1][j],dp[i][j+1],dp[i][j1]),0if mat[i][j] = 1if mat[i][j] = 0

思路

BFS

  • 某点距离0最近的距离,是要考虑它和所有0的情况的
  • 所以,我们开始的时候,应该把所有mat[i][j]=0的位置加入队列,然后一圈一圈的往外遍历

动态规划

  • 如何初始化部分dp,以支持递推?

    • 我们注意到,如果按照上面的递推方程,每个点要考虑4个方向,但是四个邻居到0的最近距离不一定被确定

      x x x
      x ? x
      x x x 		确定中间的dp时,四周邻居的dp不一定都确定
      
    • 所以,我们至少需要遍历四次,分别从四个方向开始,可以确保该方向的邻居到0的最近距离一定存在

    • 但是注意到,实际上我们初始化dp可以从左上方到右下方开始,能够确保该点的左边和上边的邻居的dp值一定存在

      同理,初始化dp从右下到左上,能够确保该点的下边和右边的邻居的dp值一定存在

代码

BFS

class Solution {
public:
   
    int dir[4][2] = {
        {1,0},{-1,0},{0,-1},{0,1}
    };
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
        int m = mat.size(), n = mat[0].size();
        vector<vector<int>> res(m,vector<int>(n,-1));		// 初始化为-1,因为0是有效的值
        queue<pair<int,int>> queue_node;
        for (int i = 0 ; i < m; ++i) 
            for (int j = 0; j < n; ++j) 
                if (mat[i][j] == 0) res[i][j]=0,queue_node.push({i,j});		// 将所有一开始的0进队列
        
        while(!queue_node.empty()) {
            int size = queue_node.size();
            while(size--) {
                auto node = queue_node.front(); queue_node.pop();
                for (int i = 0; i < 4; ++i) {
                    int next_x = node.first + dir[i][0];
                    int next_y = node.second + dir[i][1];
                    if (next_x >= 0 && next_x < m &&
                        next_y >= 0 && next_y < n &&  res[next_x][next_y] == -1		// 位置合法并且没有访问过
                    ){
                        res[next_x][next_y] = res[node.first][node.second] + 1;		// 相较于原始点,多加了一层,所以加1
                        queue_node.push({next_x,next_y});
                    }
                }
            }
        }
        return res;
    }
};

动态规划

class Solution {
public:
  
    // dp[i][j]:mat[i][j]最近的 0 的距离
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
        int m = mat.size(), n = mat[0].size();
        vector<vector<int>> dp(m,vector<int>(n,10002));     // 注意这里初始化的dp的值是一个 
        for (int i = 0 ; i < m; ++i) 
            for (int j = 0; j < n; ++j) 
                if (mat[i][j] == 0) dp[i][j] = 0;
        
        // 左上
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                // 每次都会尝试左边和上边的邻居去更新改点dp值
                if (i - 1 >= 0) {
                    dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1);
                }
                if (j - 1 >= 0) {
                    dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1);
                }
                
            }
        }
        // 右下
         for (int i = m - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                if (i + 1 < m) {
                    dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1);
                }
                if (j + 1 < n) {
                    dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1);
                }
            }
        }
        return dp;

    }
};
举报

相关推荐

0 条评论