leetcode-542. 01矩阵
动态规划(dp)
题目详情
给定一个由 0
和 1
组成的矩阵 mat
,请输出一个大小相同的矩阵,其中每一个格子是 mat
中对应位置元素到最近的 0
的距离。
两个相邻元素间的距离为 1
。
示例1:
输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]
示例2:
输入:mat = [[0,0,0],[0,1,0],[1,1,1]]
输出:[[0,0,0],[0,1,0],[1,2,1]]
思路:
这道题也可以利用bfs对每个位置四个方向搜索,但是复杂度较高,我们可以利用dp数组记录每个位置距离0最近的距离,从左上到右下遍历一次,只和左和上两个方向比较更新,顺便将所有0的位置的dp置0,再来一次右下到左上的遍历,只和右和下两个方向比较更新,即处理完了四个方向的搜索
我的代码:
class Solution
{
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat)
{
if (mat.empty()) return {};
int m = mat.size(), n = mat[0].size();
vector<vector<int>> dp(m, vector<int>(n, INT_MAX - 1)); //因为后面用到min,所以这里全初始化为最大值
//从左上到右下进行一次搜索,只考虑左和上的0,取较小距离
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (mat[i][j] == 0) //0的格子就是0
dp[i][j] = 0;
//遇到不是0的格子
else
{
if (j > 0) //不是左边缘,防止↓越界
{
dp[i][j] = min(dp[i][j], dp[i][j-1] + 1); //和左边的dp比较更新dp
}
if (i > 0) //不是上边缘,防止↓越界
{
dp[i][j] = min(dp[i][j], dp[i-1][j] + 1); //和上边dp的比较更新dp
}
}
}
}
//从右下到左上进行第二次搜索,只考虑右和上的0,取较小距离
for (int i = m - 1; i >= 0; --i)
{
for (int j = n - 1; j >= 0; --j)
{
if (mat[i][j] != 0) //第一次搜索已经将所有0的格子的dp置为0了,所以这里只需保证遍历格子不为0即可
{
if (j < n - 1) //不是右边缘,防止↓越界
{
dp[i][j] = min(dp[i][j], dp[i][j+1] + 1); //和右边的dp比较更新dp
}
if (i < m - 1) //不是下边缘,防止↓越界
{
dp[i][j] = min(dp[i][j], dp[i+1][j] + 1); //和下边的dp比较更新dp
}
}
}
}
return dp;
}
};
涉及知识点:
1.动态规划(dp)