代码随想录算法训练营第三十九天 | 62. 不同路径、63. 不同路径 II

33 阅读3分钟

62. 不同路径

链接

文章链接

题目链接

第一想法

这道题二维数组是比较好理解的,但是我直接写了一维数组,因为我觉得一维数组也不难。先说下dp数组的含义dp[i]是走到i格是的方法数,初始化是dp[0]=1,默认在起点是一种方法,递推公式为 arr[j] = (arr[j - 1] || 0) + arr[j] arr[j-1]是左边的一个格,等号右边的arr[j]是上面的一个格,等号左边的arr[j]是走到当前格的方法数,代码如下:

function uniquePaths(m: number, n: number): number {
  let arr: number[] = new Array(n).fill(0)//dp数组 
  arr[0] = 1//初始化
  for (let i = 0; i < m; i++) { //第几行
    for (let j = 0; j < n; j++) {
      arr[j] = (arr[j - 1] || 0) + arr[j] //第几列
    }
  }
  return arr[arr.length - 1]//终点
}

看完文章后的想法

文章用了两种方法,数论和动态规划,这里尝试一下用二维数组来写,代码如下:

function uniquePaths(m: number, n: number): number {
  let arr: number[][] = new Array(m)
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(n).fill(1)
  }
  for (let i = 1; i < m; i++) {
    for (let j = 1; j < n; j++) {
      arr[i][j] = arr[i][j - 1] + arr[i - 1][j]
    }
  }
  return arr[m - 1][n - 1]
}

思考

这道题不算很难,一维数组的也能想到,主要是要把dp数组的含义以及递归方程写出来就好了

63. 不同路径 II

链接

文章链接

题目链接

第一想法

这道题和不同路径是类似的,dp数组以及初始化都是一样的,唯一不一样的就是在算递推公式的时候要判断,如果当前是障碍物,则把走到当前的路径设置为0就可以了

function uniquePathsWithObstacles(obstacleGrid: number[][]): number {
  let arr: number[] = new Array(obstacleGrid[0].length).fill(0)
  arr[0] = 1
  for (let i = 0; i < obstacleGrid.length; i++) {
    for (let j = 0; j < obstacleGrid[i].length; j++) {
      if (obstacleGrid[i][j] == 1) arr[j] = 0 //多加这个条件就可以了
      else {
        arr[j] = (arr[j - 1] || 0) + arr[j]
      }
    }
  }
  return arr[arr.length - 1]
}

看完文章后的想法

文章用了一维数组和二维数组两种方法,下面的是二维数组的方法,不过我的代码和文章中的有所区别,所以想看文章的写法可以去代码随想录中查看,这里初始化就比较复杂了,原因看这张图:

image.png 因为第一行和第一列有障碍的话,则在障碍后的地点都是到达不了的

function uniquePathsWithObstacles(obstacleGrid: number[][]): number {
  let arr: number[][] = new Array(obstacleGrid.length)
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(obstacleGrid[0].length).fill(0) //都设置为0
  }
  for (let i = 0; i < arr.length && obstacleGrid[i][0] == 0; i++) {
    arr[i][0] = 1 //初始化第一列
  }
  for (let i = 0; i < arr[0].length && obstacleGrid[0][i] == 0; i++) {
    arr[0][i] = 1 //初始化第一行
  }
  for (let i = 1; i < obstacleGrid.length; i++) {
    for (let j = 1; j < obstacleGrid[i].length; j++) {
      if (obstacleGrid[i][j] === 1) arr[i][j] = 0 //当前是障碍物,则把走到当前的路径数设置为0
      else arr[i][j] = arr[i][j - 1] + arr[i - 1][j]
    }
  }
  return arr[obstacleGrid.length - 1][obstacleGrid[0].length - 1]
}

思考

这道题我觉得一维数组比二维数组简单,因为一维数组的初始化简单,而二维数组的初始化比较复杂,对于删选条件都是一样的,所以我觉得一维数组比较简单。

今日总结

今日耗时2小时,不算太难