64最小路径和-hot100-动态规划-Java

48 篇文章 0 订阅

说明:问题描述来源leetcode

一、问题描述:

64最小路径和
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例 1:   输入:grid = [[1,3,1],[1,5,1],[4,2,1]]     输出:7    解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:    输入:grid = [[1,2,3],[4,5,6]]     输出:12
提示:  m == grid.length    n == grid[i].length     1 <= m, n <= 200    0 <= grid[i][j] <= 100

二、题解

思路1-回溯(超时)

class Solution {
    int target;
    int[][] grid;
    int row;
    int column;

    public int minPathSum(int[][] grid) {
        target = Integer.MAX_VALUE;
        this.grid = grid;
        row = grid.length - 1;
        column = grid[0].length - 1;
        backTracking(0, 0, grid[0][0]);
        return target;
    }

    private void backTracking(int i, int j, int sum) {
        if (target < sum) return;//剪枝
        if (i == row && j == column) {
            target = sum;
            return;
        }
        if (i < row) backTracking(i + 1, j, sum + grid[i + 1][j]);
        if (j < column) backTracking(i, j + 1, sum + grid[i][j + 1]);
    }
}

先测试:

@Test
public void testSolution(){
    int[][][] arr = {
            {
                    {1,3,1},{1,5,1},{4,2,1}//7
            },
            {
                    {1,2,3},{4,5,6}//12
            },

    };

    for (int i = 0; i < arr.length; i++) {
        System.out.println(Arrays.deepToString(arr[i]) + "`result is " + minPathSum(arr[i]));
    }
}

发现在本地测试可以通过。

提交到leetcode平台,结果:60/61,超时,炸裂!

但是起码思路和代码是没错的,本来一眼回溯,果然还是报错了。当时也想到了贪心和dynamic plan,应该是往剩下两个方向走了。

后面把二维数组放局部变量也一样杯水车薪,改变不了超时的结果。

思路2

就来动态规划吧,这个题有类似的题目:[70爬楼梯] (https://blog.csdn.net/ws_please/article/details/129509853)、62不同路径63不同路径2

这里得出的规律就是:

第i行第j列的坐标是(i,j),当前坐标数值为grid[i][j],那么到达这个点的最小路径和是min(到达左边最小路径和+当前坐标数值,到达上面最小路径和 + 当前坐标数值)。

题解:

class Solution {
    int[][] grid;

    public int minPathSum(int[][] grid) {
        this.grid = grid;
        int row = grid.length;
        int column = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                if (i == 0 && j == 0) continue;
                setMinPathForPoint(i, j);
            }
        }
        return grid[row - 1][column - 1];
    }

    private void setMinPathForPoint(int i, int j) {
        int upSum = Integer.MAX_VALUE;
        if (i != 0) upSum = grid[i][j] + grid[i - 1][j];

        int leftSum = Integer.MAX_VALUE;
        if (j != 0) leftSum = Math.min(upSum, grid[i][j] + grid[i][j - 1]);

        grid[i][j] = Math.min(leftSum, upSum);
    }
}

后面想了想,这个能不能化成一维数组,这个是可以的,可以化成2个长度为column的一维数组,不过真没必要。因为没必要开辟2个数组,本来就可以利用输入的数组了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值