zoukankan      html  css  js  c++  java
  • LeetCode 120. Triangle (三角形最小路径和)详解

    题目详情

    给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

    例如,给定三角形:

    [
         [2],
        [3,4],
       [6,5,7],
      [4,1,8,3]
    ]
    

    自顶向下的最小路径和为 11(即,3 + 1 = 11)。

    说明:

    如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。


    解决代码(1)—— 空间复杂度为O(N^2)

    解决思路

    这个题目非常明显的动态规划问题, 当前节点的最小值由前面一层的一个(当为第一个或最后一个点)或两个节点决定, 所以维护一个二维数组,保存到达每个节点的最小路径值,通过递推式求出所有的点的最小路径值,然后返回最后一层的最小值就是目标值了

    //递推式可以很容易看出
    //中间点
    minPath[i][j] = min(minPath[i-1][j-1] + triangle[i][j], minPath[i-1][j] + triangle[i][j]);
    
    

    代码及注释

    class Solution {
    public:
        int minimumTotal(vector<vector<int>>& triangle) {
        	//minPath 表示走到当前点的最小路径
            vector<vector<int>> minPath = triangle;
            int n = triangle.size();
            
            for (int i = 1; i < n; i++) {
                for (int j = 0; j <= i; j++) {
                   //当计算节点是头结点或者尾节点时,走到此节点的路径只有一个
                    if (j == 0) {
                        minPath[i][j] = minPath[i - 1][j] + triangle[i][j];
                    } else if (j == i) {
                        minPath[i][j] = minPath[i - 1][j - 1] + triangle[i][j];
                    } else {
                    	//当非头尾节点的时候, 走到节点的方式有两种
                         minPath[i][j] = min(minPath[i-1][j-1] + triangle[i][j], minPath[i-1][j] + triangle[i][j]);
                    }
                }
            }
            //返回最后一层节点的最小路径的最小值 即目标值
            return *min_element(minPath[n-1].begin(), minPath[n-1].end());
            
        }
    };
    

    解决代码(二) 空间复杂度为O(N)

    解决思路

    题目给了提示, 可以优化到空间为O(N)

    其实不需要存所有的点, 或者说有些点用完后就不会在用了, 比如我算第三层, 那么第一层的值就用不到了, 所以我们只需维护两个个大小为N数组 保存当前层和上一层就可以优化到O(N)了!

    基本想法和解法1 相同, 就不给出代码了

    解决代码(三)自底向上

    解法二准确来说还是用了2个数组O(2N), 是否能用一个数组来解决问题呢?

    解决思路

    因为上一层的每个点到下一层都有两种方式,通过反推,由最后一层一直推到第一层。

    有递推式

    minPath[i] = 当前点值 + min(上一层的左边点值, 上一层的右边点值)

    代码如下

    class Solution {
    public:
        int minimumTotal(vector<vector<int> > &triangle) 
        {
            vector<int> minPath= triangle[triangle.size()-1];
            for ( int i = triangle.size() - 2; i>= 0 ; --i )
                for ( int j = 0; j < triangle[i].size() ; ++ j )
                    minPath[j] = triangle[i][j] + min(minPath[j],minPath[j+1]);
            return minPath[0];
        }
    };
    ```x
    
  • 相关阅读:
    shell习题第21题:计算数字的个数
    shell习题第20题:统计文件大小
    萌新小白
    编程第一天
    萌新报道
    linux下安装php扩展pdo_oci和oci8
    安装Hadoop伪分布式踩过的坑
    zabbix安装过程
    MySQL_索引
    mysql复制
  • 原文地址:https://www.cnblogs.com/qq874455953/p/9901063.html
Copyright © 2011-2022 走看看