【LeetCode】64. 最小路径和

leetcode

 

解题思路

最小路径和问题是一个经典的​​动态规划问题​​。由于机器人只能​​向下或向右移动​​,因此到达网格中任意位置 (i, j) 的最小路径和只可能来自其上方 (i-1, j) 或左方 (i, j-1)。通过构建状态转移方程,我们可以逐步计算出每个位置的最小路径和,最终得到右下角的最优解。

关键步骤

  1. ​​边界初始化​​:

    • ​​起点​​:dp[0][0] = grid[0][0]
    • ​​第一行​​:只能从左向右移动 → dp[0][j] = dp[0][j-1] + grid[0][j]
    • ​​第一列​​:只能从上向下移动 → dp[i][0] = dp[i-1][0] + grid[i][0]
  2. ​​状态转移​​:

    • 对于非边界位置 (i, j)
      dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
      表示从上方或左方的最小路径和中取较小值,加上当前位置的值。
  3. ​​空间优化​​:

    • 使用​​一维数组​​代替二维数组,空间复杂度从 O(mn) 降至 O(n)(n为列数)。

代码实现

func minPathSum(grid [][]int) int {
    if len(grid) == 0 || len(grid[0]) == 0 {
        return 0
    }

    m, n := len(grid), len(grid[0])
    dp := make([]int, n)

    // 初始化第一行
    dp[0] = grid[0][0]
    for j := 1; j < n; j++ {
        dp[j] = dp[j-1] + grid[0][j]
    }

    // 动态规划主循环
    for i := 1; i < m; i++ {
        // 更新当前行首列(只能从上方来)
        dp[0] += grid[i][0]

        // 更新当前行其他列
        for j := 1; j < n; j++ {
            dp[j] = min(dp[j], dp[j-1]) + grid[i][j]
        }
    }
    return dp[n-1]
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
} 

示例测试

func main() {
    // 示例 1
    grid1 := [][]int{{1, 3, 1}, {1, 5, 1}, {4, 2, 1}}
    fmt.Println(minPathSum(grid1)) // 输出: 7 (路径: 1→3→1→1→1)

    // 示例 2
    grid2 := [][]int{{1, 2, 3}, {4, 5, 6}}
    fmt.Println(minPathSum(grid2)) // 输出: 12 (路径: 1→2→3→6)

    // 边界测试:单行单列
    grid3 := [][]int{{5}}
    fmt.Println(minPathSum(grid3)) // 输出: 5
}
 

复杂度分析

​​指标​​​​值​​​​说明​​
​​时间复杂度​​ O(mn) 需遍历网格中每个元素一次(m为行数,n为列数)
​​空间复杂度​​ O(n) 使用一维数组存储列方向的状态值(n为列数),优化了二维数组的 O(mn) 空间

关键点总结

    1. ​​最优子结构​​:
      每个位置的最小路径和仅依赖其​​上方和左方​​的相邻状态,符合动态规划特性。

    2. ​​空间优化核心​​:

      • 一维数组 dp[j] 在更新前存储​​上一行同列​​的值(dp[j]
      • 更新过程中从左向右计算,dp[j-1] 存储​​当前行左列​​的值。
    3. ​​边界处理​​:
      第一行和第一列需要单独初始化,因为其移动方向唯一。

    4. ​​状态转移顺序​​:
      必须按​​从上到下、从左到右​​的顺序遍历,确保依赖状态已计算完成。 

    5. ​​与DFS/BFS对比​​:
      动态规划时间复杂度远优于DFS/BFS(后者在网格中可能达指数级)。

posted @ 2025-06-16 17:55  云隙之间  阅读(26)  评论(0)    收藏  举报