- Minimun Path Sum与120. Triangle题目类似。
64. Minimum Path Sum
题目
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Example:
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation:
Because the path 1→3→1→1→1 minimizes the sum.
思路与解法
此题目计算从(1,1)
走到矩阵右下角所经过的所有数字之和的最小值(每一步只能向下或者向右)。
此题目与leetcode | 63. Unique Paths Ⅱ类似,不过状态转移方程稍有不同:首先,dp[i][j]
表示从(1,1)
走到矩阵(i,j)
位置所经过的所有数字之和的最小值,则dp[i][j]
即为dp[i-1][j]
和dp[i][j-1]
中的较小值,加上grid[i][j]
。即dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i-1][j-1]
。
代码实现(Go)
// 定义MAX_INT,用于初始化dp数组
const MAX_INT = int(^uint(0) >> 1)
// 自定义函数返回num1和num2中的较小值
func min(num1, num2 int) (minn int) {
minn = num1
if minn > num2 {
minn = num2
}
return
}
func minPathSum(grid [][]int) int {
rows := len(grid)
cols := len(grid[0])
dp := make([][]int, 0)
// 初始化dp,默认无穷大
for i:=0; i<=rows; i++ {
row := make([]int, cols+1)
dp = append(dp, row)
for j:=0; j<=cols; j++ {
dp[i][j] = MAX_INT
}
}
// 由于我们第一步计算dp[1][1],需要用到dp[1][0]和dp[0][1],所以我们需要将其置为0
dp[0][1] = 0
dp[1][0] = 0
for i:=1; i<=rows; i++ {
for j:=1; j<=cols; j++ {
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i-1][j-1]
}
}
return dp[rows][cols]
}
此题目中,我们可以不额外申请dp数组,直接使用grid来进行计算,但需要做一些限定,防止数组越界。
120. Triangle
题目
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only
extra space, where n is the total number of rows in the triangle.
思路与解法
以上题类似,我们可以得到状态转移方程如下:
dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + triangle[i][j]
dp[i][j]
表示从Triangle顶部元素走到(i,j)
位置所经过的所有数字之和的最小值。
代码实现(Go)
// 定义无穷大
const MAX_INT = int(^uint(0) >> 1)
// 自定义函数返回num1和num2中的较小值
func min(num1, num2 int) (minn int) {
minn = num1
if minn > num2 {
minn = num2
}
return
}
func minimumTotal(triangle [][]int) int {
rows := len(triangle)
cols := 1
for i:=1; i<rows; i++ {
cols = len(triangle[i])
for j:=0; j<cols; j++ {
// 特别处理边界
if j == 0 {
triangle[i][j] += triangle[i-1][j]
} else if j == cols - 1 {
triangle[i][j] += triangle[i-1][j-1]
} else {
triangle[i][j] += min(triangle[i-1][j], triangle[i-1][j-1])
}
}
}
// 查找Triangle最下层的最小值
minn := MAX_INT
for j:=0; j<cols; j++ {
if minn > triangle[rows-1][j] {
minn = triangle[rows-1][j]
}
}
return minn
}
注意事项
此题目要求额外申请的空间限制在
之内,所以我便没有定义dp数组,而是在triangle的基础上进行计算,所以需要额外处理边界问题。
除此之外,cols
的初始值也需要额外注意。代码中计算triangle[i][j]
时i
从1
开始遍历,所以triangle[0][0]
并不是通过计算得到,所以如果我们的输入数据为[[num]]
类型,即只有一个数字,则返回值即应该为triangle[0][0]
。通过对查找Triangle最下层的最小值的循环可以得知cols
的初始值应该为1,即为第0行数据的长度。