leetcode | 64. Minimum Path Sum & 120. Triangle

  1. 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 O ( n ) O(n) 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
}

注意事项

此题目要求额外申请的空间限制在 O ( N ) O(N) 之内,所以我便没有定义dp数组,而是在triangle的基础上进行计算,所以需要额外处理边界问题。
除此之外,cols的初始值也需要额外注意。代码中计算triangle[i][j]i1开始遍历,所以triangle[0][0]并不是通过计算得到,所以如果我们的输入数据为[[num]]类型,即只有一个数字,则返回值即应该为triangle[0][0]。通过对查找Triangle最下层的最小值的循环可以得知cols的初始值应该为1,即为第0行数据的长度。

猜你喜欢

转载自blog.csdn.net/liuyh73/article/details/83795455