返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现求最小路径和
  • 654
分享到

C++实现求最小路径和

2023-06-20 16:06:26 654人浏览 安东尼
摘要

本篇内容主要讲解“c++实现求最小路径和”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++实现求最小路径和”吧!Minimum Path Sum 最小路径和Given a m&nbs

本篇内容主要讲解“c++实现求最小路径和”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++实现求最小路径和”吧!

Minimum Path Sum 最小路径和

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

Example:

Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.

这道题给了我们一个只有非负数的二维数组,让找一条从左上到右下的路径,使得路径和最小,限定了每次只能向下或者向右移动。一个常见的错误解法就是每次走右边或下边数字中较小的那个,这样的贪婪算法获得的局部最优解不一定是全局最优解,因此是不行的。实际上这道题跟之前那道 Dungeon Game 没有什么太大的区别,都需要用动态规划 Dynamic Programming 来做,这应该算是 DP 问题中比较简单的一类,我们维护一个二维的 dp 数组,其中 dp[i][j] 表示到达当前位置的最小路径和。接下来找状态转移方程,因为到达当前位置 (i, j)  只有两种情况,要么从上方 (i-1, j) 过来,要么从左边 (i, j-1) 过来,我们选择 dp 值较小的那个路径,即比较 dp[i-1][j] 和 dp[i][j-1],将其中的较小值加上当前的数字 grid[i][j],就是当前位置的 dp 值了。但是有些特殊情况要提前赋值,比如起点位置,直接赋值为 grid[0][0],还有就是第一行和第一列,其中第一行的位置只能从左边过来,第一列的位置从能从上面过来,所以这两行要提前初始化好,然后再从 (1, 1) 的位置开始更新到右下角即可,反正难度不算大,代码如下:

解法一:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        if (grid.empty() || grid[0].empty()) return 0;        int m = grid.size(), n = grid[0].size();        vector<vector<int>> dp(m, vector<int>(n));        dp[0][0] = grid[0][0];        for (int i = 1; i < m; ++i) dp[i][0] = grid[i][0] + dp[i - 1][0];        for (int j = 1; j < n; ++j) dp[0][j] = grid[0][j] + dp[0][j - 1];        for (int i = 1; i < m; ++i) {            for (int j = 1; j < n; ++j) {                dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]);            }        }        return dp[m - 1][n - 1];    }};

我们可以优化空间复杂度,可以使用一个一维的 dp 数组就可以了,初始化为整型最大值,但是 dp[0][0] 要初始化为0。之所以可以用一维数组代替之前的二维数组,是因为当前的 dp 值只跟左边和上面的 dp 值有关。这里我们并不提前更新第一行或是第一列,而是在遍历的时候判断,若j等于0时,说明是第一列,我们直接加上当前的数字,否则就要比较是左边的 dp[j-1] 小还是上面的 dp[j]  小,当是第一行的时候,dp[j] 是整型最大值,所以肯定会取到 dp[j-1] 的值,然后再加上当前位置的数字即可,参见代码如下:

解法二:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        if (grid.empty() || grid[0].empty()) return 0;        int m = grid.size(), n = grid[0].size();        vector<int> dp(n, INT_MAX);        dp[0] = 0;        for (int i = 0; i < m; ++i) {            for (int j = 0; j < n; ++j) {                if (j == 0) dp[j] += grid[i][j];                else dp[j] = grid[i][j] + min(dp[j], dp[j - 1]);            }        }        return dp[n - 1];    }};

我们还可以进一步的优化空间,连一维数组都不用新建,而是直接使用原数组 grid 进行累加,这里的累加方式跟解法一稍有不同,没有提前对第一行和第一列进行赋值,而是放在一起判断了,当i和j同时为0时,直接跳过。否则当i等于0时,只加上左边的值,当j等于0时,只加上面的值,否则就比较左边和上面的值,加上较小的那个即可,参见代码如下:

解法三:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        if (grid.empty() || grid[0].empty()) return 0;        for (int i = 0; i < grid.size(); ++i) {            for (int j = 0; j < grid[i].size(); ++j) {                if (i == 0 && j == 0) continue;                if (i == 0) grid[0][j] += grid[0][j - 1];                else if (j == 0) grid[i][0] += grid[i - 1][0];                else grid[i][j] += min(grid[i - 1][j], grid[i][j - 1]);            }        }        return grid.back().back();    }};

下面这种写法跟上面的基本相同,只不过用了 up 和 left 两个变量来计算上面和左边的值,看起来稍稍简洁一点,参见代码如下:

解法四:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        if (grid.empty() || grid[0].empty()) return 0;        for (int i = 0; i < grid.size(); ++i) {            for (int j = 0; j < grid[i].size(); ++j) {                if (i == 0 && j == 0) continue;                int up = (i == 0) ? INT_MAX : grid[i - 1][j];                int left = (j == 0) ? INT_MAX : grid[i][j - 1];                grid[i][j] += min(up, left);            }        }        return grid.back().back();    }};

到此,相信大家对“C++实现求最小路径和”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: C++实现求最小路径和

本文链接: https://lsjlt.com/news/298236.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++实现求最小路径和
    本篇内容主要讲解“C++实现求最小路径和”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++实现求最小路径和”吧!Minimum Path Sum 最小路径和Given a m&nbs...
    99+
    2023-06-20
  • C++实现LeetCode(64.最小路径和)
    [LeetCode] 64. Minimum Path Sum 最小路径和 Given a m x n grid filled with no...
    99+
    2024-04-02
  • C++实现LeetCode(124.求二叉树的最大路径和)
    [LeetCode] 124. Binary Tree Maximum Path Sum 求二叉树的最大路径和 Given a non-empty binary ...
    99+
    2024-04-02
  • C++怎么求二叉树的最大路径和
    本篇内容主要讲解“C++怎么求二叉树的最大路径和”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++怎么求二叉树的最大路径和”吧!求二叉树的最大路径和Given a non-empty...
    99+
    2023-06-20
  • Java实现Floyd算法求最短路径
    本文实例为大家分享了Java实现Floyd算法求最短路径的具体代码,供大家参考,具体内容如下import java.io.FileInputStream; import java.io.FileNotFoundException; impo...
    99+
    2023-05-30
  • 三角形最小路径和
    给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。例如,给定三角形:[     [2],    [3,4],   [6,5,7], ...
    99+
    2023-06-02
  • C++最短路径Dijkstra算法如何实现
    这篇文章主要介绍“C++最短路径Dijkstra算法如何实现”,在日常操作中,相信很多人在C++最短路径Dijkstra算法如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++最短路径Dijkstra...
    99+
    2023-07-05
  • Python和Matlab怎么实现蚂蚁群算法求解最短路径
    这篇文章主要介绍“Python和Matlab怎么实现蚂蚁群算法求解最短路径”,在日常操作中,相信很多人在Python和Matlab怎么实现蚂蚁群算法求解最短路径问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”P...
    99+
    2023-06-29
  • JavaScript网格中的最小路径怎么实现
    这篇“JavaScript网格中的最小路径怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript网格中的...
    99+
    2023-07-02
  • c++求数组最大最小值函数的实现
    目录求数组元素最大最小值函数c++中min和max函数求数组元素最大最小值函数 #include<iostream> #include<algorithm> ...
    99+
    2024-04-02
  • C#图表算法之最短路径怎么实现
    本篇内容主要讲解“C#图表算法之最短路径怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#图表算法之最短路径怎么实现”吧!从一个顶点到达另一个顶点的成本最小的路径。我们采用一个一般性的模...
    99+
    2023-06-30
  • C++实现LeetCode(112.二叉树的路径和)
    [LeetCode] 112. Path Sum 二叉树的路径和 Given a binary tree and a sum, determine if the tree has a...
    99+
    2024-04-02
  • 怎么用awk命令实现求和、求平均值、求最大值、求最小值
    本篇内容介绍了“怎么用awk命令实现求和、求平均值、求最大值、求最小值”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、求和代码如下:cat...
    99+
    2023-06-13
  • c++怎么求数组的最大和最小值
    本篇内容主要讲解“c++怎么求数组的最大和最小值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“c++怎么求数组的最大和最小值”吧!求数组元素最大最小值函数#include<iostream...
    99+
    2023-07-02
  • python3实现Dijkstra算法最短路径的实现
    问题描述 现有一个有向赋权图。如下图所示: 问题:根据每条边的权值,求出从起点s到其他每个顶点的最短路径和最短路径的长度。 说明:不考虑权值为负的情况,否则会出现负值圈问题。 ...
    99+
    2024-04-02
  • C++实现LeetCode(71.简化路径)
    [LeetCode] 71.Simplify Path 简化路径 Given an absolute path for a file (Unix-style), simplify i...
    99+
    2024-04-02
  • c#最小值怎么求
    c# 中求最小值的方法有两种:使用 math.min() 方法比较数值表达式并返回最小值。使用 linq 的 min() 方法求取集合中最小元素的值。 C# 中的最小值求法 在 C# ...
    99+
    2024-05-12
    c#
  • 怎么使用c语言动态规划求解最短路径
    在C语言中使用动态规划求解最短路径,可以按照以下步骤进行:1. 定义一个二维数组来表示图中各个节点之间的距离。假设有n个节点,则可以...
    99+
    2023-08-18
    c语言
  • Java利用Dijkstra和Floyd分别求取图的最短路径
    目录1 最短路径的概述2 杰斯特拉(Dijkstra)算法2.1 原理2.2 案例分析3 弗洛伊德(Floyd)算法3.1 原理3.2 案例分析4 邻接矩阵加权图实现5 邻接表加权图...
    99+
    2024-04-02
  • Python 最短路径的几种求解方式
    目录...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作