leetcode 542. 01 矩阵 --javascript DP

542. 01 矩阵

题目:

给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每个格子是 mat 中对应位置元素到最近的 0 的距离。算法

两个相邻元素间的距离为 1 。数组

image.png

题解

动态规划(Dynamic Programming, DP)

  • 动态规划只能应用于有最优 子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能彻底知足,故有时须要引入必定的近似)。markdown

  • 简单地说,问题可以分解成子问题来解决oop

  • 通俗一点来说,动态规划和其它遍历算法(如深/广度优先搜索)都是将原问题拆成多个子问题而后求解,他们之间最本质的区别是,动态规划保存子问题的解,避免重复计算spa

  • 解决动态规划问题的关键是找到状态转移方程,这样咱们能够通计算和储存子问题的解来求解最终问题code

  • 同时,咱们也能够对动态规划进行空间压缩,起到节省空间消耗的效果。orm

  • 在一些状况下,动态规划能够当作是带有状态记录(memoization)的优先搜索leetcode

  • 动态规划是自下而上的,即先解决子问题,再解决父问题;get

  • 而用带有状态记录的优先搜索自上而下的,即从父问题搜索到子问题,若重复搜索到同一个子问题则进行状态记录,防止重复计算。it

  • 若是题目需求的是最终状态,那么使用动态搜索比较方便;

  • 若是题目须要输出全部的路径,那么使用带有状态记录的优先搜索会比较方便。

回到本题目

一种办法是使用一个 dp 数组作 memoization,使得广

度优先搜索不会重复遍历相同位置;另外一种更简单的方法是,咱们从左上到右下进行一次动态搜

索,再从右下到左上进行一次动态搜索。两次动态搜索便可完成四个方向上的查找。

coding

/**
 * @param {number[][]} mat
 * @return {number[][]}
 */
var updateMatrix = function(mat) {
   if(!mat.length) return {};
   let n = mat.length, m = mat[0].length;
   const dp = Array.from({length: n}, ()=> new Array(m).fill(m+n));
   for(let i = 0; i < n; i++) {
       for(let j = 0; j < m; j++) {
           if(mat[i][j] === 0) {
               dp[i][j] = 0
           }else {
                if(j > 0)
                  dp[i][j] = Math.min(dp[i][j], dp[i][j-1] + 1);
                if(i > 0)
                  dp[i][j] = Math.min(dp[i][j], dp[i-1][j] + 1)
           }
       }
   }
      for(let i = n-1; i >= 0; i--) {
       for(let j = m-1; j >= 0; j--) {
           if(mat[i][j]) {
                if(j < m-1)
                  dp[i][j] = Math.min(dp[i][j], dp[i][j+1] + 1);
                if(i < n-1)
                  dp[i][j] = Math.min(dp[i][j], dp[i+1][j] + 1)
           }
       }
   }
   return dp;
};
复制代码
相关文章
相关标签/搜索