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

目录

题目

例子

[示例 1:](#示例 1:)

[示例 2:](#示例 2:)

前言

思路

思想

代码

调用的函数

主函数

所有代码

力扣提交的代码

运行结果

小结


题目

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

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 ii + 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]的最小值。

从底下迭代是一种方法

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

比如上面的例子:

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

思想

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

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

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

有些相当于广度优先了

那么思想有了

就是代码实现了

代码

调用的函数

cpp 复制代码
int minimumTotal(vector<vector<int>>& triangle) {
    int length_1 = triangle.size();
    int length_2 = triangle[length_1-1].size();
    vector <vector<int>> n(length_1, vector<int>(length_1, 0));
    for (int i = 0; i <= length_1 - 1; i++)
    {
        if (i == 0)
        {
            n[0][0] = triangle[0][0];
            continue;
        }
        for (int j = 0; j <= i; j++)
        {
            if (j == 0)
            {
                n[i][0] = n[i - 1][0] + triangle[i][0];
                continue;
            }
            if (j == i)
            {
                n[i][i] = n[i - 1][i - 1] + triangle[i][i];
                continue;
            }
            n[i][j] = min(n[i - 1][j - 1] + triangle[i][j], n[i - 1][j] + triangle[i][j]);
        }
    }
    int min = n[length_1 - 1][0];
    for (int i = 0; i <= length_2 - 1; i++)
        if (n[length_1 - 1][i] < min)
            min = n[length_1 - 1][i];
    return min;
}

思想就是上面讲到的思想

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

主函数

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

所有代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int minimumTotal(vector<vector<int>>& triangle) {
    int length_1 = triangle.size();
    int length_2 = triangle[length_1-1].size();
    vector <vector<int>> n(length_1, vector<int>(length_1, 0));
    for (int i = 0; i <= length_1 - 1; i++)
    {
        if (i == 0)
        {
            n[0][0] = triangle[0][0];
            continue;
        }
        for (int j = 0; j <= i; j++)
        {
            if (j == 0)
            {
                n[i][0] = n[i - 1][0] + triangle[i][0];
                continue;
            }
            if (j == i)
            {
                n[i][i] = n[i - 1][i - 1] + triangle[i][i];
                continue;
            }
            n[i][j] = min(n[i - 1][j - 1] + triangle[i][j], n[i - 1][j] + triangle[i][j]);
        }
    }
    int min = n[length_1 - 1][0];
    for (int i = 0; i <= length_2 - 1; i++)
        if (n[length_1 - 1][i] < min)
            min = n[length_1 - 1][i];
    return min;
}
int main()
{
    vector <vector<int>>sum_1 = { {2} ,{3,4},{6,5,7},{4,1,8,3} };
    int min = minimumTotal(sum_1);
    cout << min << endl;
    return 0;
}

力扣提交的代码

cpp 复制代码
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
    int length_1 = triangle.size();
    int length_2 = triangle[length_1-1].size();
    vector <vector<int>> n(length_1, vector<int>(length_1, 0));
    for (int i = 0; i <= length_1 - 1; i++)
    {
        if (i == 0)
        {
            n[0][0] = triangle[0][0];
            continue;
        }
        for (int j = 0; j <= i; j++)
        {
            if (j == 0)
            {
                n[i][0] = n[i - 1][0] + triangle[i][0];
                continue;
            }
            if (j == i)
            {
                n[i][i] = n[i - 1][i - 1] + triangle[i][i];
                continue;
            }
            n[i][j] = min(n[i - 1][j - 1] + triangle[i][j], n[i - 1][j] + triangle[i][j]);
        }
    }
    int min = n[length_1 - 1][0];
    for (int i = 0; i <= length_2 - 1; i++)
        if (n[length_1 - 1][i] < min)
            min = n[length_1 - 1][i];
    return min;
}
};

运行结果

小结

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

(入了个门,相当于?)

相关推荐
JingHongB2 分钟前
代码随想录算法训练营Day55 | 图论理论基础、深度优先搜索理论基础、卡玛网 98.所有可达路径、797. 所有可能的路径、广度优先搜索理论基础
算法·深度优先·图论
weixin_432702265 分钟前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
小冉在学习8 分钟前
day52 图论章节刷题Part04(110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 )
算法·深度优先·图论
Repeat7159 分钟前
图论基础--孤岛系列
算法·深度优先·广度优先·图论基础
小冉在学习11 分钟前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论
武子康23 分钟前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
passer__jw7671 小时前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
Ocean☾1 小时前
前端基础-html-注册界面
前端·算法·html
顶呱呱程序1 小时前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
爱吃生蚝的于勒1 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法