携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
不同路径
本题是力扣62题,求不同路径
一个机器人位于一个 m x n 网格的左上角。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
- 拿到这个题,可以先找出对应的状态转移方程:
dp[i][j]=dp[i-1][j]+dp[i][j-1]
动态规划求解如下:(时间复杂度mn,空间复杂度mn)
function uniquePaths (m, n) {
let dp = new Array(m).fill(0).map(() => new Array(n).fill(0))
for (let i = 0; i < m; i++) {
dp[i][0] = 1
}
for (let j = 0; j < n; j++) {
dp[0][j] = 1
}
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1]
}
}
return dp[m-1][n-1]
};
看到这个击败人数,就知道此方案有些垃圾。那我们就优化一下
状态压缩,空间复杂度优化如下:(时间复杂度mn,空间复杂度n)
这里的优化其实是每次存储当前位置和上一个位置即可。
function uniquePaths (m, n) {
let cur = new Array(n).fill(1)
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
cur[j] = cur[j-1] + cur[j]
}
}
return cur[n-1]
};
三角形的最小路径和
本题是力扣120题
题目: 给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。
- 拿到这个题,我们首先可以找到对应的状态转移方程,即为
dp[i][j] = Math.min(dp[i+1][j],dp[i+1][j+1]) + triangle[i][j]
function minimumTotal (triangle) {
let n = triangle.length
if (!n) {
return 0
}
let dp = new Array(n)
// 初始化二维数组dp
for (let i = 0; i < n; i++) {
dp[i] = new Array(triangle[i].length)
}
// 最后一层可以初始化数据
for (let j = 0; j < triangle[n-1].length; j++) {
dp[n-1][j] = triangle[n-1][j]
}
// 处理转移子问题,自底向上
for (let i = n - 2; i >= 0; i--) {
for (let j = 0; j < triangle[i].length; j++) {
dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j]
}
}
return dp[0][0]
};
和上题一样,我们可以状态压缩,节省空间复杂度:
function minimumTotal (triangle) {
let n = triangle.length
if (!n) {
return 0
}
let dp = []
// 最后一层可以初始化数据
for (let j = 0; j < triangle[n-1].length; j++) {
dp[j] = triangle[n-1][j]
}
// 处理转移子问题,自底向上
for (let i = n - 2; i >= 0; i--) {
for (let j = 0; j < triangle[i].length; j++) {
dp[j] = Math.min(dp[j], dp[j+1]) + triangle[i][j]
}
}
return dp[0]
};