面试必刷算法TOP101之DP篇 TOP3

三角形最小路径和

题目来源:Leetcode
1、问题描述:
给定一个三角形 triangle ,找出自顶向下的最小路径和。

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

示例:
在这里插入图片描述
2、思路解析
思路一:

在这里插入图片描述
在这里插入图片描述

思路二:
在这里插入图片描述

3、代码实现
思路一:

class Solution {
public:
        int minimumTotal(vector<vector<int>>& triangle) {
        int row = triangle.size();
        int col = triangle[row-1].size();
        vector<vector<int>> t(triangle);
        for (int i = 1;i < row;i++) {
            for (int j = 0;j <= i;j++) {
                //每行的第一列不需要比大小直接是当前值加上上一行的当前列
                if (j == 0) {
                    t[i][j] = t[i - 1][j] + triangle[i][j];
                }
                else if (j == i) {
                    //最后一列
                    t[i][j] = t[i - 1][i - 1] + triangle[i][i];
                }
                else {
                    //中间列
                    t[i][j] = min(t[i - 1][j], t[i - 1][j - 1]) + triangle[i][j];
                }
            }
        }
        int ret = t[row - 1][0];
        //在全部中间结果中选一个最小的中间结果作为全局状态
        for (int i = 1;i < col;i++) {
            ret = min(ret, t[row - 1][i]);
        }
        return ret;
    }
};

需要不断的判断边界情况,处理不好可能会栈一出
思路二

class Solution {
public:
        int minimumTotal(vector<vector<int>>& triangle) {

         int row = triangle.size();
        int col = triangle[row-1].size();
        vector<vector<int>> t(triangle);
        //从倒数第二行开始
        for (int i = row-2;i >=0;i--) {
            for (int j = 0;j <= i;j++) {
         
                    //中间列
                    t[i][j] = min(t[i + 1][j], t[i + 1][j + 1]) + triangle[i][j];
                
            }
        }
       
        return t[0][0];
    }
};
//简化版不需要开辟新空间用来存储中间值。
class Solution {
public:
        int minimumTotal(vector<vector<int>>& triangle) {

         int row = triangle.size();
        int col = triangle[row-1].size();
       
        //从倒数第二行开始
        for (int i = row-2;i >=0;i--) {
            for (int j = 0;j <= i;j++) {
         
                    //中间列
                    triangle[i][j] = min(triangle[i + 1][j], triangle[i + 1][j + 1]) + triangle[i][j];
                
            }
        }
       
        return triangle[0][0];
    }
};

不需要考虑边界问题,也不用考虑栈移除,简化版没有了空间的开辟

不同的路径

题目来源:Leetcode

1、问题描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例:
在这里插入图片描述

2、思路解析
在这里插入图片描述

3、代码实现

class Solution {
public:
    int uniquePaths(int m, int n) {
   
   vector<vector<int>> v;
        v.resize(m);
      
        //v[0][]=v[][1]=1;
        for (int i = 0;i < m;i++) {    
            v[i].resize(n);
            v[i][0] = 1;
        }
        for (int i = 0;i < n;i++) {
     
            v[0][i] = 1;
        }

        //到达(i,j)点的路线条数是到达前一个节点(i-1,j)的路径个数加上到达上一个节点(i,j-1)的路径个数之和
        for (int i = 1;i < m;i++) {
            for (int j = 1;j < n;j++) {
                v[i][j] = v[i][j - 1] + v[i - 1][j];
            }
        }
        //返回最后一行
        return v[m - 1][n - 1];
    }
};
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自首的小偷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值