• 【力扣】三角形最小路径和


    目录

    题目

    例子

    示例 1:

    示例 2:

    前言

    思路

    思想

    代码

    调用的函数

    主函数

    所有代码

    力扣提交的代码

    运行结果

    小结


    题目

    给定一个三角形 triangle ,找出自顶向下的最小路径和。

    每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

    例子

    示例 1:

    输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
    输出:11
    解释:如下面简图所示:
       2
      3 4
     6 5 7
    4 1 8 3
    自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
    

    示例 2:

    输入:triangle = [[-10]]
    输出:-10
    
    

    前言

    本题是动态规划的一道经典题目,最早出现在1994年的ioi比赛中

    经过了20多年的时间,如今已经变成了动态规划的入门必做题

    思路

    我们可以以下面的图来举例子

    设置数据为一个二维数组(或者是一个容器)

    放入[2],[3,4],[6,5,7],[4,1,8,3]四组数据

    我们可以很简单的看出来——最短路径是2,3,5,1

    如果把走到响应的点所得到的和(也就是所求值)定义为一个二维数组的话

    我们可以得到一个4*4的二维数组(当然其中有一些是用不到了)

    那可以把题目转化为求最底下行数组的值,并且比较大小得出最小值

    我可以知晓除去第一列的值,其中随机一列的值只取决上一列与其相邻的值,因此我们可以设置递归函数,第a[i][j]的值只取决与原来数组本身的值加上a[i-1][j]与a[i-1][j-1]的最小值。

    从底下迭代是一种方法

    但是他会有一个问题,他会重复大量计算相同的数字

    比如上面的例子:

    第三行第一列以及第二列都需要知道第二行第一列的数字,所以第二行第一列的值会计算两遍

    思想

    所以结果就是我从上向下迭代

    下一行的数字只会取上一行的值,然而上一行的值都是计算好的

    不需要重新计算也不存在重复以及浪费时间

    有些相当于广度优先了

    那么思想有了

    就是代码实现了

    代码

    调用的函数

    1. int minimumTotal(vectorint>>& triangle) {
    2. int length_1 = triangle.size();
    3. int length_2 = triangle[length_1-1].size();
    4. vector int>> n(length_1, vector<int>(length_1, 0));
    5. for (int i = 0; i <= length_1 - 1; i++)
    6. {
    7. if (i == 0)
    8. {
    9. n[0][0] = triangle[0][0];
    10. continue;
    11. }
    12. for (int j = 0; j <= i; j++)
    13. {
    14. if (j == 0)
    15. {
    16. n[i][0] = n[i - 1][0] + triangle[i][0];
    17. continue;
    18. }
    19. if (j == i)
    20. {
    21. n[i][i] = n[i - 1][i - 1] + triangle[i][i];
    22. continue;
    23. }
    24. n[i][j] = min(n[i - 1][j - 1] + triangle[i][j], n[i - 1][j] + triangle[i][j]);
    25. }
    26. }
    27. int min = n[length_1 - 1][0];
    28. for (int i = 0; i <= length_2 - 1; i++)
    29. if (n[length_1 - 1][i] < min)
    30. min = n[length_1 - 1][i];
    31. return min;
    32. }

    思想就是上面讲到的思想

    需要注意的是第一行以及第一列与最后一列要单独考虑

    主函数

    1. int main()
    2. {
    3. vector int>>sum_1 = { {2} ,{3,4},{6,5,7},{4,1,8,3} };
    4. int min = minimumTotal(sum_1);
    5. cout << min << endl;
    6. return 0;
    7. }

    所有代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. int minimumTotal(vectorint>>& triangle) {
    6. int length_1 = triangle.size();
    7. int length_2 = triangle[length_1-1].size();
    8. vector int>> n(length_1, vector<int>(length_1, 0));
    9. for (int i = 0; i <= length_1 - 1; i++)
    10. {
    11. if (i == 0)
    12. {
    13. n[0][0] = triangle[0][0];
    14. continue;
    15. }
    16. for (int j = 0; j <= i; j++)
    17. {
    18. if (j == 0)
    19. {
    20. n[i][0] = n[i - 1][0] + triangle[i][0];
    21. continue;
    22. }
    23. if (j == i)
    24. {
    25. n[i][i] = n[i - 1][i - 1] + triangle[i][i];
    26. continue;
    27. }
    28. n[i][j] = min(n[i - 1][j - 1] + triangle[i][j], n[i - 1][j] + triangle[i][j]);
    29. }
    30. }
    31. int min = n[length_1 - 1][0];
    32. for (int i = 0; i <= length_2 - 1; i++)
    33. if (n[length_1 - 1][i] < min)
    34. min = n[length_1 - 1][i];
    35. return min;
    36. }
    37. int main()
    38. {
    39. vector int>>sum_1 = { {2} ,{3,4},{6,5,7},{4,1,8,3} };
    40. int min = minimumTotal(sum_1);
    41. cout << min << endl;
    42. return 0;
    43. }

    力扣提交的代码

    1. class Solution {
    2. public:
    3. int minimumTotal(vectorint>>& triangle) {
    4. int length_1 = triangle.size();
    5. int length_2 = triangle[length_1-1].size();
    6. vector int>> n(length_1, vector<int>(length_1, 0));
    7. for (int i = 0; i <= length_1 - 1; i++)
    8. {
    9. if (i == 0)
    10. {
    11. n[0][0] = triangle[0][0];
    12. continue;
    13. }
    14. for (int j = 0; j <= i; j++)
    15. {
    16. if (j == 0)
    17. {
    18. n[i][0] = n[i - 1][0] + triangle[i][0];
    19. continue;
    20. }
    21. if (j == i)
    22. {
    23. n[i][i] = n[i - 1][i - 1] + triangle[i][i];
    24. continue;
    25. }
    26. n[i][j] = min(n[i - 1][j - 1] + triangle[i][j], n[i - 1][j] + triangle[i][j]);
    27. }
    28. }
    29. int min = n[length_1 - 1][0];
    30. for (int i = 0; i <= length_2 - 1; i++)
    31. if (n[length_1 - 1][i] < min)
    32. min = n[length_1 - 1][i];
    33. return min;
    34. }
    35. };

    运行结果

    小结

    本期博客介绍了现在的动态规划的经典题目,并且提供了3种方法,

    (入了个门,相当于?)

  • 相关阅读:
    openvino 将onnx转为IR并进行int8量化
    Codeforces Round #836 (Div. 2)
    (十)延迟队列
    XML与html解析,区别,如何使用
    QT笔记——QT工具uic,rcc,moc,qmake的使用和介绍
    Java-jar包,反编译为:.java文件
    学会背包问题
    python3基础语法
    1000万条数据分页方法,redis提高访问速度,减少数据库压力
    CVE-2017-7529 Nginx越界读取内存漏洞
  • 原文地址:https://blog.csdn.net/mumuemhaha/article/details/132921886