问题描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
输入:m = 3, n = 7
输出:28
做题思路
给定终点,不同方向不同路径,或者每步步数不定,典型的动态规划题目
动态规划三要素:1.重叠子问题 2.最优子结构 3.状态转移方程
- 重叠子问题 走到(m,n)位置的路径,由走到(m, n-1)路径数量和走到(m-1,n)路径数量组成
- 最优子结构
- 状态转移方程
f(m,n)=f(m−1,n)+f(m,n−1)
f(i, 0) = 1, i < m
f(0, j) = 1, j < n
code
var uniquePaths = function(m, n) {
const arr = [];
for(let i = 0; i < m; i++) {
arr[i] = [];
arr[i][0] = 1;
}
for(let j = 0; j<n; j++) {
arr[0][j] = 1;
}
for(let i=1;i<m;i++) {
for(let j=1;j<n;j++) {
arr[i][j] = arr[i-1][j] + arr[i][j-1];
}
}
return arr[m-1][n-1];
};
延伸题
不同路径 II
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
解题思路: 当有0时把当前点置0,边界中若f(i,0)有障碍,则 i< j < m都要置0
var uniquePathsWithObstacles = function(obstacleGrid) {
const n = obstacleGrid.length, m = obstacleGrid[0].length;
const arr = createArray(m,n);
arr[0][0] = obstacleGrid[0][0] ? 0 : 1;
for(let i= 1;i<m;i++) {
arr[0][i] = obstacleGrid[0][i] === 1 ? 0 : arr[0][i-1];
}
for(let j=1;j<n;j++) {
arr[j][0] = obstacleGrid[j][0] === 1 ? 0 : arr[j-1][0];
}
for(let i = 1; i< m; i++) {
for(let j=1;j<n;j++) {
arr[j][i] = obstacleGrid[j][i] === 1 ? 0 : arr[j-1][i] + arr[j][i-1];
}
}
return arr[n-1][m-1];
};
function createArray(m,n) {
return new Array(n).fill('').map(() => new Array(m).fill(0));
}
路径最小和
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
把(m,n)上的数字表示成a(m,n),路径(m,n)上数字最小和为Sum(m,n)
Sum(m,n) = Math.min(Sum(m-1,n), Sum(m, n-1)) + a(m,n)
表中的数据把路径之和替换为路径的最小数
var minPathSum = function(grid) {
const n = grid.length, m = grid[0].length;
const arr = createArray(m,n);
arr[0][0] = grid[0][0];
for(let i = 1; i < m; i++) {
arr[0][i] = arr[0][i-1] + grid[0][i];
}
for(let j = 1; j < n; j++) {
arr[j][0] = arr[j-1][0] + grid[j][0];
}
for(let i = 1; i<m; i++) {
for(let j =1; j<n;j++) {
arr[j][i] = grid[j][i] + Math.min(arr[j][i-1], arr[j-1][i]);
}
}
return arr[n-1][m-1];
};
function createArray(m,n) {
return new Array(n).fill('').map(()=>new Array(m).fill(0));
}