00 问题

00-1 描述

对给定高度为n的一个整数三角形,找出从顶部到底部的最小路径和。每个整数只能向下移动到与之相邻的整数。

找到一个一样的力扣题:120. 三角形最小路径和 - 力扣(LeetCode) (leetcode-cn.com)

示例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

00-2 提示:

1 <= triangle.length <= 200
triangle[0].length == 1
triangle[i].length == triangle[i - 1].length + 1
-104 <= triangle[i][j] <= 104

01 思路

想用动态规划写出来,重点在于状态转移方程。

将等腰三角形抽象为等腰直角三角形,如下

  0 1 2 3
0 2
1 3 4
2 6 5 7
3 8 3 9 2

加上下标化的序列,我们就可以用二维数组dp来考虑。dp是用来存储到i,j位置后用到的最短路径长度,比如dp[2] [2]=2+4+7=13

定义一个起点:

dp[0][0] = a[0][0];

三种情况:

  1. 三角形左路,在直角图里就是第一列,满足:

    dp[i][0]=dp[i-1][0];
  2. 三角形右路,在直角图里是对角线,满足:

    dp[i][i]=dp[i-1][i-1]+a[i][i]
  3. 普通位置

    dp[i][j]=min(dp[i-1][j-1],dp[i-1][j])+a[i][j];

这样程序就很好写了。就是往dp数组里填数就行,最后筛出最后一行的最小值就行。

02 代码

class Solution {
public:
   int minimumTotal(vector<vector<int>>& triangle) {
       int len = triangle.size();
       int dp[200][200]={0};
       dp[0][0]=triangle[0][0];
       for(int i=1;i<len;i++){
           dp[i][0] = dp[i-1][0]+triangle[i][0];
      }
       for(int i=1;i<len;i++){
           dp[i][i] = triangle[i][i]+dp[i-1][i-1];
      }
       for(int i=2;i<len;i++){
           for(int j=1;j<i;j++){
               dp[i][j] = triangle[i][j]+min(dp[i-1][j], dp[i-1][j-1]);
          }
      }
       //填充dp
       //下面筛选路径最短
       int ans = dp[len-1][0];
       for(int j = 1;j < len;j++){
           if(dp[len-1][j]<ans){
               ans = dp[len-1][j];
          }
      }
       return ans;
  }
};

03 升级版--记录路径

03-1 思路

如果要记下路径,需要再来一个二维数组pre来记录坐标为i,j的点的前一个节点。那么如何记录呢?我们看一下:

  • (i,i)的前一个节点就是(i-1,i-1);

  • (i,j)的前一个节点是(i-1,j)或者(i-1,j-1);

  • (i,0)的前一个节点是(i-1,0)。

容易从这些情况总结出,上一节点一定为i-1,只需记录j的值即可。故我们在pre二维数组里记录的就是当前节点的前一节点的j值。

记录之后,我们还需要输出这个最小路径。怎么输出呢?

我们在前一问题的基础上得到最后行的最小值的列值后,将它返回主控函数,并用它作为参数给路径输出函数Disppath。

输出方法为:

  • 对于当前节点,入栈,查它的pre数组值,更新,继续该操作,直到完成。

    更新操作为:

     path.push_back(a[i][k]);
    k=pre[i][k];
  • 逐个出栈。

03-2 代码

//三角形最小路径
#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
#define MAXN 100
int a[MAXN][MAXN];//三角形
int n;//高度
int ans = 0;//应求的路径长度
int dp[MAXN][MAXN];
int pre[MAXN][MAXN];//前驱结点
//根据状态转移方程,只记录列号即可
int Search(){
   int i,j;
   dp[0][0] = a[0][0];
   for(i=1;i<n;i++){
       dp[i][0]=dp[i-1][0]+a[i][0];
       pre[i][0]=i-1;
  }
   for(i=1;i<n;i++){
       dp[i][i]=dp[i-1][i-1]+a[i][i];
       pre[i][i]=i-1;
  }
   for(i=2;i<n;i++){
       for(j=1;j<i;j++){
           if(dp[i-1][j-1]<dp[i-1][j]){
               dp[i][j]=dp[i-1][j-1]+a[i][j];
               pre[i][j]=j-1;
          }
           else{
               dp[i][j]=dp[i-1][j]+a[i][j];
               pre[i][j]=j;          
          }
      }
  }
   ans = dp[n-1][0];
   int k=0;
   for ( j = 1; j < n; j++)
  {
       if(ans>dp[n-1][j]){
           ans = dp[n-1][j];
           k=j;
      }
  }
   return k;
}
void Disppath(int k){
   int i=n-1;
   vector<int>path;//路径节点
   while(i>=0){
       path.push_back(a[i][k]);
       k=pre[i][k];
       i--;
  }
   vector<int>::reverse_iterator it;
   for(it=path.rbegin();it!=path.rend();++it){
       printf("%d ",*it);
  }
   printf("\n");
}

int main(){
   int k;//k行k列的三角形
   memset(pre, 0, sizeof(pre));
   memset(dp, 0, sizeof(dp));
   scanf("%d",&n);
   for(int i=0;i<n;i++){
       for(int j=0;j<=i;j++){
           scanf("%d",&a[i][j]);
      }
  }
   k=Search();
   Disppath(k);
   printf("%d\n",ans);
   return 0;
}

算法学习->求解三角形最小路径及其值的更多相关文章

  1. 算法学习->求解三角形最小路径

    00 问题 00-1 描述 对给定高度为n的一个整数三角形,找出从顶部到底部的最小路径和.每个整数只能向下移动到与之相邻的整数. 找到一个一样的力扣题:120. 三角形最小路径和 - 力扣(LeetC ...

  2. 算法学习记录-图——最小路径之Floyd算法

    floyd算法: 解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包. 设为从到的只以集合中的节点为中间节点的最短路径的长度. 若最短路径经过 ...

  3. leetcode 120. 三角形最小路径和 及 53. 最大子序和

    三角形最小路径和 问题描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  4. [leetcode-120] 三角形最小路径和

    三角形最小路径和 (1过) 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  5. 领扣-120 三角形最小路径和 Triangle MD

    三角形最小路径和 Triangle 数组 动态规划 问题 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [2], [3,4], [6,5,7], ...

  6. Java实现 LeetCode 120 三角形最小路径和

    120. 三角形最小路径和 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  7. 1. 线性DP 120. 三角形最小路径和

    经典问题: 120. 三角形最小路径和  https://leetcode-cn.com/problems/triangle/ func minimumTotal(triangle [][]int) ...

  8. [算法]LeetCode 120:三角形最小路径和

    题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3]]自顶向下的最小路径和 ...

  9. LeetCode(120):三角形最小路径和

    Medium! 题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

随机推荐

  1. 腾讯云 CIF 工程效能峰会,10 月 19 - 20 日震撼来袭!

    近年来,依托于云计算的飞速发展,腾讯云云产品更新迅猛,云原生生态构建初具规模,越来越多的企业也开始寻求与深入数字化转型之路.但在摸索与实践中,企业往往会进入"伪上云"的误区.除了单 ...

  2. django forms的常用命令及方法(一)

    根据别人网上发布,个人爱好收集 Form表单的功能 自动生成HTML表单元素 检查表单数据的合法性 如果验证错误,重新显示表单(数据不会重置) 数据类型转换(字符类型的数据转换成相应的Python类型 ...

  3. Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】

    正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的\(n\)个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 \(1\leq n\ ...

  4. IDEA连接Mysql数据库之后,在Mapper.xml编写SQL时不会自动提示表信息问题(非常详细!)

    1.首先得连接上数据库 (一)点击IDEA右侧数据库模块 (二)选择MySql进行连接 (三)填写数据库相关配置 (四)重点!!! 这个时候点击测试连接是连接不上的,需要设置时区 (按照如下设置) ( ...

  5. windows下如何查看所有端口及占用

    1.在windows下查看所有端口: 先点击电脑左下角的开始,然后选择运行选项,接着我们在弹出的窗口中,输入[cmd]命令,进行命令提示符. 然后我们在窗口中输入[netstat -ano]按下回车, ...

  6. 前端快闪三:多环境灵活配置react

    你已经使用Create React App脚手架搭建了React应用,现在该部署了. 一般会使用npm run build或者yarn build构建出静态资源, 由web服务器承载. 您会体验到 多 ...

  7. NOIP 模拟六 考试总结

    T1辣鸡 T1就搞得这莫不愉快.. 大致题意是给你几个矩形,矩形覆盖的点都标记上,每个矩形无重复部分,求满足(x,y) (x+1,y+1)都标记过的点对数,范围1e9. 看起来很牛的样子,我确实也被1 ...

  8. Linux安装配置Java

    先从 Oracle 官网下载 Java 运行 tar -zxvf xxxx.tar.gz 指令将 Java 解压到 /usr/local/java 下(个人习惯,无所谓) 修改环境变量 vim /et ...

  9. 使用CEF(二)— 基于VS2019编写一个简单CEF样例

    使用CEF(二)- 基于VS2019编写一个简单CEF样例 在这一节中,本人将会在Windows下使用VS2019创建一个空白的C++Windows Desktop Application项目,逐步进 ...

  10. Java编译运行环境讨论(复古但能加深对Java项目的理解)

    Java编译运行环境讨论(复古但能加深对Java项目的理解) 如今我们大多数情况都会使用IDE来进行Java项目的开发,而一个如今众多优秀的IDE已经能够帮助我们自动的部署并调试运行我们的Java程序 ...