矩阵的最小路径和

描述
给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
示例1
输入:
[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]

返回值:
12
方法一:暴力递归:
因为是从左上角到右下角,只能向右或者向下,

可以使用递归,
把问题简化为:当前位置(i, j)和右边位置(i + 1, j)和下面位置(i, j + 1)之间的问题
base case:

当i == row - 1 && j == col - 1时,位于矩阵右下角,即为最终结果

当i == row - 1时,位于最后一行,此时只能向右走

当j == col - 1时,位于最右一行,此时只能向下走

当位于矩阵中间某个位置时(i, j),此时要判断右边位置(i + 1, j)和下面位置(i, j + 1)中的值谁大谁小
代码:

public int minPathSum(int matrix[][],int i,int j){
        //如果(i,j)就是右下角的元素
        if(i==matrix.length-1&&j==matrix[0].length-1){
            return matrix[i][j];
        }
        //如果(i,j)在右边界上,只能向下走
        if(j==matrix[0].length-1){
            return matrix[i][j]+minPathSum(matrix,i+1,j);
        }
        //如果(i,j)在下边界上,只能向右走
        if(i==matrix.length-1){
            return matrix[i][j]+minPathSum(matrix,i,j+1);
        }
        int left=minPathSum(matrix,i,j+1);
        int down=minPathSum(matrix,i+1,j);
        return matrix[i][j]+Math.max(left,down);
    }在这里插入代码片

方法二;动态规划

import java.util.Arrays; 
public class Solution {
    public int minPathSum(int[][] grid) {
        if (grid == null) {
            return 0;
        }
        int rowLen = grid.length;
        int colLen = grid[0].length;
        int[] res = new int[colLen + 1];
        Arrays.fill(res, Integer.MAX_VALUE);
        res[1] = 0;
        for (int i = 1; i <= rowLen; i++) {
            for (int j = 1; j <= colLen; j++) {
                //当前点的最小路径和为 : 从左边和上边选择最小的路径和再加上当前点的值
                //res[j]没更新之前就表示i-1行到第j个元素的最小路径和
                //因为是从左往右更新,res[j-1]表示i行第j-1个元素的最小路径和
                res[j] = Math.min(res[j], res[j - 1]) + grid[i - 1][j - 1];
            }
        }
        return res[colLen];
    }
}
### 寻找矩阵最小路径问题的递归解法 对于给定的一个 m×n 的网格 `grid`,目标是从左上角走到右下角,并使所经过路径上的数值总最小。每次移动只能向下或向右。 #### 递归方法解析 为了计算从起点到终点的最短路径,在任意位置 `(i,j)` 处的最优解等于当前位置的值加上其下方 `(i+1,j)` 或右侧 `(i,j+1)` 中较小的那个位置的最佳路径[^1]: ```c #include <limits.h> #include <stdio.h> int minPathSumUtil(int grid[][3], int row, int col, int m, int n); // 辅助函数用于返回两个整数之间的最小值 int min(int x, int y) { return (x < y)? x : y; } // 主要功能:求取从(0,0)到达(m-1,n-1)处的最小路径 int minPathSum(int grid[][3], int m, int n){ // 调用辅助函数并传入初始坐标以及行列大小参数 return minPathSumUtil(grid, 0, 0, m, n); } // 实际执行递归逻辑的功能定义 int minPathSumUtil(int grid[][3], int row, int col, int m, int n){ // 如果越界则返回极大值表示不可达 if(row >= m || col >= n) return INT_MAX; // 当前格子就是目的地时直接返回该格子内的权值 if(row==m-1 && col==n-1) return grid[row][col]; // 否则选择下一步往右边走还是往下边走更优的结果再加上当前节点权重作为最终结果返回 return grid[row][col] + min(minPathSumUtil(grid, row+1, col, m, n), minPathSumUtil(grid, row, col+1, m, n)); } ``` 此代码片段展示了如何通过递归来解决这个问题。然而需要注意的是这种方法存在大量的重复计算,因此效率较低。可以考虑采用记忆化技术来优化性能,即将已经计算过的中间状态保存起来以便后续重用[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值