算法学习->求解三角形最小路径及其值
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];
三种情况:
三角形左路,在直角图里就是第一列,满足:
dp[i][0]=dp[i-1][0];
三角形右路,在直角图里是对角线,满足:
dp[i][i]=dp[i-1][i-1]+a[i][i]
普通位置
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;
}
算法学习->求解三角形最小路径及其值的更多相关文章
- 算法学习->求解三角形最小路径
00 问题 00-1 描述 对给定高度为n的一个整数三角形,找出从顶部到底部的最小路径和.每个整数只能向下移动到与之相邻的整数. 找到一个一样的力扣题:120. 三角形最小路径和 - 力扣(LeetC ...
- 算法学习记录-图——最小路径之Floyd算法
floyd算法: 解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包. 设为从到的只以集合中的节点为中间节点的最短路径的长度. 若最短路径经过 ...
- leetcode 120. 三角形最小路径和 及 53. 最大子序和
三角形最小路径和 问题描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
- [leetcode-120] 三角形最小路径和
三角形最小路径和 (1过) 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
- 领扣-120 三角形最小路径和 Triangle MD
三角形最小路径和 Triangle 数组 动态规划 问题 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [2], [3,4], [6,5,7], ...
- Java实现 LeetCode 120 三角形最小路径和
120. 三角形最小路径和 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
- 1. 线性DP 120. 三角形最小路径和
经典问题: 120. 三角形最小路径和 https://leetcode-cn.com/problems/triangle/ func minimumTotal(triangle [][]int) ...
- [算法]LeetCode 120:三角形最小路径和
题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3]]自顶向下的最小路径和 ...
- LeetCode(120):三角形最小路径和
Medium! 题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
随机推荐
- html正文提取工具goose的安装及简单使用Demo
1.git clone https://github.com/grangier/python-goose.git 2.cd python-goose 3.sudo pip install -r req ...
- 华为云计算IE面试笔记-Fusionsphere架构及组件介绍(服务器虚拟化解决方案)
eDSK 最上层则是eDSK是我们FusionSphere服务器虚拟化解决方案中的虚拟化北向统一API接口,其他的第三方系统或者是其他运营平台(FC.VMware等)可以通过eDSK轻松完成无缝对 ...
- 牛客练习赛89E-牛牛小数点【数论】
正题 题目链接:https://ac.nowcoder.com/acm/contest/11179/E 题目大意 定义\(f(x)\)表示\(\frac{1}{x}\)的混循环节长度(如果没有循环节就 ...
- 吴恩达-神经网络-week1-hw3
Ref:https://blog.csdn.net/u013733326/article/details/79702148 点击查看代码 from testCases import * from pl ...
- 【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
问题描述 使用微软Azure AD,对授权进行管理.通过所注册应用的OAuth API(https://login.chinacloudapi.cn/{TENANT ID}/oauth2/v2.0/t ...
- Mybatis初始化机制
对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程. 1.MyBatis的初始化做了什么 2. MyBatis基于XML配置 ...
- keras框架下的深度学习(一)手写体识别
这个系列文章主要记录使用keras框架来搭建深度学习模型的学习过程,其中有一些自己的想法和体会,主要学习的书籍是:Deep Learning with Python,使用的IDE是pycharm. 在 ...
- ZK(ZooKeeper)分布式锁实现
点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你. 本文中案例都会在上传到git上,请放心浏览 git地址:https://github.com/muxiaonong/Zo ...
- SpringCloud微服务实战——搭建企业级开发框架(五):数据库持久化集成MySql+Druid+MyBatis-Plus
在引入相关数据库持久化相关依赖库之前,我们可以考虑到,当我们因业务开发需要,引入各种各样的依赖库时,Jar包冲突是我们必须面对的一个问题,Spring为了解决这些Jar包的冲突,推出了各种bom, ...
- 什么是Sprint计划?
Sprint 计划是Scrum框架中的一个事件,团队将确定他们将在冲刺期间处理的产品积压项目,并讨论他们完成这些产品积压项目的初始计划. 团队可能会发现建立冲刺目标很有帮助,并以此为基础确定他们在冲刺 ...