题目描述

给定一个由 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,如果用DFS有超时的风险。

BFS

  1. 遍历matrix矩阵,将所有\(matrix[i][j]=0\)的位置信息\((i, j)\)保存到队列中,所有\(matrix[i][j]=1\)的将值从1改到定义的无穷大。
  2. 当队列不为空的时候,持续循环:
    • 从队列中弹出一个元素,获取位置信息,将该位置(i,j)的上下左右做个判断,如果某个位置上的值大于matrix[i][j]+1,那么将该值改为matrix[i][j]+1,重新压入队列
    • 进行改值操作的时候注意边界条件

BFS代码

  1. #define INF 10000
  2. class Solution {
  3. vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
  4. int row = matrix.size();
  5. if (row == 0)
  6. return matrix;
  7. int col = matrix[0].size();
  8. queue<pair<int, int> > myQueue;
  9. for (int i = 0; i < row; i++)
  10. {
  11. for (int j = 0; j < col; j++)
  12. {
  13. if (matrix[i][j] == 0)
  14. myQueue.push(pair<int, int>(i, j));
  15. else
  16. matrix[i][j] = INF;
  17. }
  18. }
  19. while (!myQueue.empty())
  20. {
  21. pair<int, int> rec = myQueue.front();
  22. myQueue.pop();
  23. if (rec.first-1 >= 0 && matrix[rec.first-1][rec.second] > matrix[rec.first][rec.second]+1)
  24. {
  25. matrix[rec.first-1][rec.second] = matrix[rec.first][rec.second]+1;
  26. myQueue.push(pair<int, int>(rec.first-1, rec.second));
  27. }
  28. if (rec.second-1 >= 0 && matrix[rec.first][rec.second-1] > matrix[rec.first][rec.second]+1)
  29. {
  30. matrix[rec.first][rec.second-1] = matrix[rec.first][rec.second]+1;
  31. myQueue.push(pair<int, int>(rec.first, rec.second-1));
  32. }
  33. if (rec.first+1 < row && matrix[rec.first+1][rec.second] > matrix[rec.first][rec.second]+1)
  34. {
  35. matrix[rec.first+1][rec.second] = matrix[rec.first][rec.second]+1;
  36. myQueue.push(pair<int, int>(rec.first+1, rec.second));
  37. }
  38. if (rec.second+1 < col && matrix[rec.first][rec.second+1] > matrix[rec.first][rec.second]+1)
  39. {
  40. matrix[rec.first][rec.second+1] = matrix[rec.first][rec.second]+1;
  41. myQueue.push(pair<int, int>(rec.first, rec.second+1));
  42. }
  43. }
  44. return matrix;
  45. }

动态规划

基本的思想就是遍历matrix,如果matrix[i][j]是0的话,dp[i][j]直接为0,否则,它与四周的dp值有关,又因为从左上到右下的更新过程中,只能确定左上角两边的dp值;

所以要再从右下角往左上角遍历,这样就把dp[i][j]四周的dp值都考虑进去了。

动态规划代码

  1. class Solution {
  2. vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
  3. // 两次遍历,左上到右下和右下到左上,更新完的dp就是最终的答案
  4. int row = matrix.size();
  5. if (row == 0)
  6. return matrix;
  7. int col = matrix[0].size();
  8. vector<vector<int> > dp(row, vector<int>(col));
  9. if (matrix[0][0] == 0)
  10. dp[0][0] = 0;
  11. else
  12. dp[0][0] = INF;
  13. // 第一次
  14. for (int i = 1; i < col; i++)
  15. {
  16. if (matrix[0][i] == 0)
  17. dp[0][i] = 0;
  18. else
  19. dp[0][i] = min(INF, dp[0][i-1] + 1);
  20. }
  21. for (int i = 1; i < row; i++)
  22. {
  23. if (matrix[i][0] == 0)
  24. dp[i][0] = 0;
  25. else
  26. dp[i][0] = min(INF, dp[i-1][0] + 1);
  27. }
  28. for (int i = 1; i < row; i++)
  29. {
  30. for (int j = 1; j < col; ++j)
  31. {
  32. if (matrix[i][j] == 0)
  33. dp[i][j] = 0;
  34. else
  35. dp[i][j] = min(INF, min(dp[i-1][j], dp[i][j-1]) + 1);
  36. }
  37. }
  38. // 打印第一次更新成果
  39. // for (int i = 0; i < row; i++)
  40. // {
  41. // for (int j = 0; j < col; j++)
  42. // cout << dp[i][j] << ' ';
  43. // cout << endl;
  44. // }
  45. //
  46. // cout << "===========我是分割线===========" << endl;
  47. // 第二次
  48. for (int i = col - 2; i >= 0; i--)
  49. {
  50. if (matrix[row-1][i] == 0)
  51. dp[row-1][i] = 0;
  52. else
  53. dp[row-1][i] = min(dp[row-1][i], dp[row-1][i+1] + 1);
  54. }
  55. for (int i = row - 2; i >= 0; i--)
  56. {
  57. if (matrix[i][col-1] == 0)
  58. dp[i][col-1] = 0;
  59. else
  60. dp[i][col-1] = min(dp[i][col-1], dp[i+1][col-1] + 1);
  61. }
  62. for (int i = row - 2; i >= 0; i--)
  63. {
  64. for (int j = col - 2; j >= 0; j--)
  65. {
  66. if (matrix[i][j] == 1)
  67. dp[i][j] = min(dp[i][j], min(dp[i+1][j], dp[i][j+1]) + 1);
  68. }
  69. }
  70. return dp;
  71. }
  72. };

【leet-code】542. 01 矩阵的更多相关文章

  1. Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)

    542. 01 矩阵 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 ...

  2. Leetcode 542.01矩阵

    01矩阵 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 ...

  3. LeetCode——542. 01 矩阵

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 ...

  4. Leetcode 542:01 矩阵 01

    Leetcode 542:01 矩阵 01 Matrix### 题目: 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . Given a matr ...

  5. leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings

    542. 01 Matrix https://www.cnblogs.com/grandyang/p/6602288.html 将所有的1置为INT_MAX,然后用所有的0去更新原本位置为1的值. 最 ...

  6. [EOJ Monthly 2018.10][C. 痛苦的 01 矩阵]

    题目链接:C. 痛苦的 01 矩阵 题目大意:原题说的很清楚了,不需要简化_(:з」∠)_ 题解:设\(r_i\)为第\(i\)行中0的个数,\(c_j\)为第\(j\)列中0的个数,\(f_{i,j ...

  7. 【Leet Code】Palindrome Number

    Palindrome Number Total Accepted: 19369 Total Submissions: 66673My Submissions Determine whether an ...

  8. MATLAB小函数:将列向量转化为0-1矩阵

    MATLAB小函数:将列向量转化为0-1矩阵 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 将列向量转化为0-1矩阵,例如 A = 1 2 1 5 3 ...

  9. Leet Code 771.宝石与石头

    Leet Code编程题 希望能从现在开始,有空就做一些题,自己的编程能力太差了. 771 宝石与石头 简单题 应该用集合来做 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S  ...

随机推荐

  1. shell中的常用条件判断

    -e :该“文件名”是否存在.exit-d :该文件名是否为目录.dir-f  :该文件名是否为普通文件.file -b:该文件是否为块文件.block -r :该文件是否具有可读属性 read-w ...

  2. List、Set、数据结构、Collections

    一.数据结构: 1.什么是数据结构: 一种数据的存储方式 2.常见的4+1种数据结构 堆栈结构: 它是只有一个开口的容器结构 特点: 先进后出(FILO) 例子:弹夹,桶装可比克 队列结构: 它是两端 ...

  3. Android开发者的Anko使用指南(一)之Intent

    使用Anko Intent帮助器可以添加如下依赖 dependencies { compile "org.jetbrains.anko:anko-commons:$anko_version& ...

  4. 运维工具pssh和pdsh安装和使用

    1. pssh安装与使用 1.1 pssh安装 [root@server]# wget http://peak.telecommunity.com/dist/ez_setup.py [root@ser ...

  5. JAVA核心技术第一卷第三章

    JAVA中包含的数据类型:

  6. ansible 关闭ssh首次连接时提示

    关闭ssh首次连接时提示. 修改/etc/ansible/ansible.cfg配置文件 方法一:(推荐,配置文件中存在) host_key_checking = False 方法二: ssh_arg ...

  7. Maven4-仓库

    坐标和构建是一个构件在Maven世界中的逻辑表示方式,而其物理表示方式是文件.Maven通过仓库来统一管理这些文件 什么是Maven仓库? 在Maven世界中,任何一个依赖,插件或者项目构建的输出,都 ...

  8. Vipe框架构思记

    准备着手写一个JAVA框架,基于公司目前的框架提取出来.当然公司现在的框架也是我搭建的.在这整理一下思路. 框架名称:Vipe AOP,IOC容器:Spring MVC:Spring MVC ORM: ...

  9. Java基础巩固——排序

    快速排序 基本思想: 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对两部分继续进行排序,直到整个序列有序. 实例: 1.一趟排序的过程: 2.排序的全 ...

  10. KVM虚拟化概述与安装

    虚拟化是构建云计算基础架构不可或缺的关键技术之一,云计算的云端系统,其实质上就是一个大型的KVM分布式系统,虚拟化通过在一个物理平台上虚拟出更多的虚拟平台,而其中的每一个虚拟平台则可以作为独立的终端加 ...