【动态规划专题】2:矩阵的最小路径和

《程序员代码面试指南--IT名企算法与数据结构题目最优解》 左程云 著

矩阵的最小路径和

【题目】
给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角位置,路径上所有的数字累加起来就是路径和,返回所有路径中最小的路径和。

【举例】
如果给定的m如下:
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12.

关键思路:
假设有一个M*N的数组 dp[M][N], dp[i][j]的值表示从左上角(0,0)位置走到(i,j)位置的最小路径和。
第0行和第0列比较特殊,是不断累加的结果
1 4 9 18
9,
14
22

其他行和列,dp[i][j] = Min(dp[i-1][j], dp[i][j-1]) + m[i][j];

所以,我们可以从最右下角,倒推到左上角。

从下到上思考,从上到下解决。

#include <iostream>
#include <stack>
#include <exception>
using namespace std;

int minOfTwoNum(int A, int B)
{
return A > B ? B : A;
}
//申请一个M*N的二位数组空间
int MinPathRoad(int* arrPath, const int rows,const int cols)
{
if (arrPath == nullptr || rows < 0 || cols < 0)
{
throw new std::exception("Invalid para");
}
if (rows == 0 || cols == 0)
{
return 0;
}
int result = 0;
int** copyPath =new int*[rows];
for (int i = 0; i < rows; i++)
{
copyPath[i] = new int[cols];
}

///这里有可优化空间。能用一维数组解决的,不要用二维数组
//for (int i = 0; i < rows; i++)
//{
//    for (int j = 0; j < cols; j++)
//    {
//    if (i == 0 && j == 0)
//    {
//    copyPath[i][j] = *(arrPath + i*cols + j);
//    }
//    if (i == 0 && j>0)
//    {
//    copyPath[i][j] = *(arrPath + i*cols + j) + *(arrPath + i*cols + j - 1);
//    }
//    if (j == 0 && i > 0)
//    {
//    copyPath[i][j] = *(arrPath + i*cols + j) + *(arrPath + (i - 1)*cols + j);
//    }
//    }
//}

copyPath[0][0] = *(arrPath);

for (int j = 1; j < cols; j++)
{
copyPath[0][j] = *(arrPath + j) + *(arrPath + j - 1);
}

for (int i = 1; i < rows; i++)
{
copyPath[i][0] = *(arrPath + i*cols ) + *(arrPath + (i - 1)*cols );
}

////时间复杂度是O(M*N)
for (int i = 1; i < rows; i++)
{
for (int j = 1; j < cols; j++)
{
int tempValue = minOfTwoNum(copyPath[i - 1][j], copyPath[i][j - 1]);
copyPath[i][j] = minOfTwoNum(copyPath[i - 1][j], copyPath[i][j - 1]) + *(arrPath + i*cols + j);
}
}

result = copyPath[rows - 1][cols - 1];

for (int i = 0; i < rows; i++)
{
delete[] copyPath[i];
}
delete[] copyPath;

return result;
}
//申请一个一维数组空间
int MinPathRoad2(int* arrPath, const int rows, const int cols)
{
if (arrPath == nullptr || rows < 0 || cols < 0)
{
throw new std::exception("Invalid para");
}
if (rows == 0 || cols == 0)
{
return 0;
}
int result = 0;
//用一个一维数组来存储临时变量
int* copyPath = new int[cols];

for (int j = 0; j < cols; j++)
{
if (j == 0)
{
copyPath[j] = *(arrPath + j);
}
if (j>0)
{
copyPath[j] = *(arrPath + 0*cols + j) + *(arrPath + 0*cols + j - 1);
}
}

for (int i = 1; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (j == 0)
{
copyPath[j] = copyPath[j] + *(arrPath + i*cols + j);
}
else
{
int tempValue = minOfTwoNum(copyPath[j], copyPath[j - 1]);
copyPath[j] = minOfTwoNum(copyPath[j], copyPath[j - 1]) + *(arrPath + i*cols + j);
}

}
}

result = copyPath[cols - 1];

delete[] copyPath;

return result;
}
//====================测试用例=================

void test1()
{
int arrPath[4][4] = { { 1, 3, 5, 9 }, { 8, 1, 3, 4 }, { 5, 0, 6, 1 }, { 8, 8, 4, 0 } };
cout << MinPathRoad((int *)arrPath, 4, 4) << endl;
}

void test2()
{
int arrPath[4][4] = { { 1, 3, 5, 9 }, { 8, 1, 3, 4 }, { 5, 0, 6, 1 }, { 8, 8, 4, 0 } };
cout << MinPathRoad2((int *)arrPath, 4, 4) << endl;
}

int main()
{
test1();
test2();

system("pause");
return 0;
}

原文地址:https://www.cnblogs.com/music-liang/p/12054353.html

时间: 2024-11-08 20:07:46

【动态规划专题】2:矩阵的最小路径和的相关文章

矩阵的最小路径和二维动态规划的空间压缩

题目:给定一个矩阵,从左上角开始每次只能向右或者向下移动,最后到达右下角的位置,路径上的所有的数字累加起来作为这条路径的路劲和.要求返回所有路径和中的最小路径和. 举例: 路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回其和12. 解析: 这个题目很类似之前的那个动态规划的数字三角的问题.毫无疑问的,这个问题也是用动态规划解决.只要确定了状态和转移方程,这个题目很容易解决.下面直接给出代码: //利用path记录路径,对于每一个path[i][j],0代表dp[i][j]的值从上

[DP]矩阵的最小路径和

题目 给定一个矩阵m, 从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的树子累加起来就是路径和,返回所有的路径中最小的路径和. 解法一 这是一道经典的动态规划题,状态转移方程为dp[i][j] = min{dp[i - 1][j], dp[i][j - 1]} + m[i][j].可以用一个二维的dp矩阵来求解.对于dp矩阵,第一行和第一列只会有一种走法,就是从左到右或者从上到下的累加,所以可以先进行初始化,然后其他元素就可以用过转移方程一个一个填充,知道把整个dp矩阵填充

4.2 矩阵的最小路径和

[题目]: 给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有路径和中最小的路径和 举例: 如果给定的m如下: 1      3      5      9 8      1      3      4 5      0      6      1 8      8      4      0 路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12 原文地址:https://www.cnblogs.com/latu

矩阵的最小路径和

给你一个数组,求从[0,0]位置到[n-1,m-1]的最短路径. 数组如图所示: 1 3 5 9 8 2 3 4 5 0 6 1 8 8 4 0 路径1→3→1→0→6→1→0是所有路径中路径和最小的,所以返回12 代码: public class MinpathSum{ //时间复杂度O(M*N),空间复杂度O(M*N) public static int minPathSum1(int[][] matrix) { if(matrix == null || matrix.length==0 |

【数据结构与算法】动态规划——最小路径和(普通矩阵、三角形两题)

最小路径和 LeetCode:最小路径和 题目描述: 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 思想: 动态规划,可以用原数组作为dp数组 代码: class Solution { public int minPathSum(int[][] grid) {

矩阵中的最小路径

package 数阵中的最优路径; import java.util.Scanner; public class Main2 { /** * 数阵中的最小路径搜索 * 1:设计要点 * 应用动态规划设计从右下角逐行至左上角,确定n,m后,随机产生的整数二维数组a(n,m)作矩阵输出同时赋值给部分和数组b(n,m). * 数组b(i,j)为点(i,j)到到右下角的最小数值和stm(i,j)是点(i,j)向右(R)或向下(D)或向右下(0)的路标数组 * 注意到最后一行与最后一列各数只有一个出口,于

LeetCode—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. 首先每一个路径的上一个路径都是来自于其上方和左方 现将最上面的路径进行求和,最左边的路径进行求和

代码题(34)— 矩阵最小路径和

1.64. 最小路径和 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 需要用动态规划Dynamic Programming来做,这应该算是DP问题中比较简单的一类,我们维护一个二维的dp数组,其中dp[i][j]表示当前位置的最小路径和,递推式也容易写出来 

#动态规划 LeetCode 120 三角形最小路径和

给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11). 说明: 如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分. 思路: 接着上一题的状态转移继续说 动态规划问题,重中之重就是找到状态转移方程,而状态转移方程很重要的一点就是明确函数的意义所在,以及记录结果