• LeetCode 64最小路径和


    题目

    给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

    说明:每次只能向下或者向右移动一步。

    示例:

    输入:
    [
      [1,3,1],
      [1,5,1],
      [4,2,1]
    ]
    输出: 7
    解释: 因为路径 1→3→1→1→1 的总和最小。
    

    解释

    此题运用的是动态规划, 而且和很多题目非常相似,题目要求每次只能向下走一步或者向右走一步。这就规定走到这一个点的路径只有两点,就是上面的点和左边的点。所以每一点的最小cost可以表示为

    min(到达上面的点的最小cost, 到达左边的点的最小cost) + 当前点的 cost
    

    这样就把问题分成子问题,创建一个二维数组cost用来保存到达每一点的最小cost。

    递归式可以表示为

      cost[i][j] = min(cost[i][j - 1] + grid[i][j], cost[i - 1][j] + grid[i][j]);
    

    然后利用一个二层循环,把到达每一个点的最小值求出来。返回返回右下角的值即可。

    代码

        int minPathSum(vector<vector<int>>& grid) {
            vector<vector<int>> cost = grid;
            int n = grid.size(), m = grid[0].size();
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
    	            //处理第一行和第一列的情况,如果不处理的话,数组会越界
                    if (i == 0) {
    	                //一直向右走
                        cost[i][j] = cost[i][j - 1] + grid[i][j];
                    } else if (j == 0) {
    	                //一直向下走
                        cost[i][j] = cost[i - 1][j] + grid[i][j];
                    } else {
    	                //利用递推式求结果
                        cost[i][j] = min(cost[i][j - 1] + grid[i][j], cost[i - 1][j] + grid[i][j]);
                    }
                }
            }
            //返回右下角值
            return cost[n-1][m-1];
        }
    

    总结

    • 关键的一点就是找出递推式。看当前最优解能否被前面的值推出
    • 存储原来的数据一般可以用一个二维数组。但是有一些题目对空间有限制。比如LeetCode 413, 这样的话就要尽量去优化,看能不能用一维数组来代替。

    类似题目

    LeetCode 877
    https://blog.csdn.net/qq874455953/article/details/82696196

  • 相关阅读:
    (转载)机器学习方法的PPT
    算法的力量(转李开复)
    CNKI免费帐号
    图像增强(二)
    初始化 Microsoft Visual SourceSafe 源代码管理提供程序时失败。您无法使用此提供程序执行源代码管理操作。”
    2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛 Fruit Ninja I
    hdu 3607 Traversal
    zoj 3686 A Simple Tree Problem
    hdu 3727 Jewel
    hdu 4366 Successor
  • 原文地址:https://www.cnblogs.com/qq874455953/p/9901064.html
Copyright © 2020-2023  润新知