ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode — 最小路径和

2022-08-29 06:01:36  阅读:219  来源: 互联网

标签:min ++ 路径 网格 最小 int grid LeetCode dp


LeetCode — 最小路径和

问题陈述

给定一个 mxn网格 用非负数填充,找到一条从左上角到右下角的路径,该路径最小化沿其路径的所有数字的总和。

笔记: 您只能在任何时间点向下或向右移动。

问题陈述取自: https://leetcode.com/problems/minimum-path-sum

示例 1:

Source: LeetCode

 输入:网格 = [[1, 3, 1], [1, 5, 1], [4, 2, 1]]  
 输出:7  
 解释:因为路径 1 → 3 → 1 → 1 → 1 使总和最小化。

示例 2:

 输入:grid = [[1, 2, 3], [4, 5, 6]]  
 输出:12

约束:

 - m == grid.length  
 - n == 网格[i].length  
 - 1 <= 米,n <= 200  
 - 0 <= 网格[i][j] <= 100

解释

蛮力方法

蛮力方法是生成从左上角到右下角的所有可能路径。我们计算所有这些路径的总和并找到最小值。该解决方案适用于小型阵列,但对于大型阵列会超时。

最优子结构

到达 (m, n) 的路径必须通过以下两个单元之一:(m - 1, n) 或 (m, n - 1)。到达(m,n)的最小成本可以计算为“两个单元格的最小值加上网格(m,n)”。

 minimumCost(m, n) = min(minimumCost(m - 1, n), minimumCost(m, n - 1)) + grid(m, n) int minCost(int grid[R][C], int m, int n)  
 {  
 如果 (n < 0 || m < 0)  
 返回 INT_MAX;  
 否则如果 (m == 0 && n == 0)  
 返回网格[m][n];  
 别的  
 返回网格[m][n] +  
 分钟(  
 minCost(网格,m - 1,n),  
 minCost(网格,m,n - 1)  
 );  
 }

动态规划

使用递归方法求解上述最优子结构。但是,如果我们仔细观察,上述方法会一次又一次地计算相同的子问题。

我们可以避免使用动态规划方法重新计算相同的子问题。我们创建一个二维数组并以自下而上的方式解决问题。

让我们跳到算法以更好地理解它。

 - 设置 m = grid.size()  
 n = 网格[0].size()  
 dp(m, 向量<int>(n))  
  
 - 循环 i = 0;我 < 米;我++  
 j = 0 的循环; j  
  
 如果我 == 0 && j == 0  
 - 设置 dp[i][j] = 网格[i][j]  
 否则如果我 == 0  
 - 设置 dp[i][j] = dp[i][j - 1] + grid[i][j]  
 否则如果 j == 0  
 - 设置 dp[i][j] = dp[i - 1][j] + grid[i][j]  
 别的  
 - 设置 dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]  
 - 结束  
  
 - 返回 dp[m - 1][n - 1]

这种方法的时间复杂度是 O(N^2) ,空间复杂度为 O(M*N) .

让我们检查一下我们的算法 C++ , 戈朗 , 和 Javascript .

C++ 解决方案

 类解决方案{  
 上市:  
 int minPathSum(向量<vector<int> >&网格){  
 int m = grid.size();  
 int n = grid[0].size();  
 向量<vector<int> > dp(m, 向量<int>(n));  
  
 for(int i = 0; i < m; i++) {  
 for(int j = 0; j < n; j++) {  
 如果(我 == 0 && j == 0){  
 dp[i][j] = 网格[i][j];  
 } 否则如果(我 == 0){  
 dp[i][j] = dp[i][j - 1] + 网格[i][j];  
 }否则如果(j == 0){  
 dp[i][j] = dp[i - 1][j] + 网格[i][j];  
 } 别的 {  
 dp[i][j] = min(dp[i- 1][j], dp[i][j - 1]) + 网格[i][j];  
 }  
 }  
 }  
  
 返回 dp[m - 1][n - 1];  
 }  
 };

Golang 解决方案

 func minPathSum(grid [][]int) int {  
 m := 长度(网格)  
 n := len(grid[0])  
 dp := make([][]int, m)  
  
 对于 k := 范围 dp {  
 dp[k] = make([]int, n)  
 }  
  
 对于我:= 0;我 < 米;我++ {  
 对于 j := 0; j < n; j++ {  
 如果我 == 0 && j == 0 {  
 dp[i][j] = 网格[i][j]  
 } 否则如果我 == 0 {  
 dp[i][j] = dp[i][j - 1] + 网格[i][j]  
 } 否则如果 j == 0 {  
 dp[i][j] = dp[i - 1][j] + 网格[i][j]  
 } 别的 {  
 dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + 网格[i][j]  
 }  
 }  
 }  
  
 返回 dp[m - 1][n - 1]  
 }  
  
 func min(a, b int) int {  
 如果 a < b {  
 返回一个  
 }  
 返回 b  
 }

Javascript 解决方案

 var minPathSum = 函数(网格){  
 让 m = grid.length;  
 让 n = grid[0].length;  
 让 dp = 新数组(m);  
  
 for(让 k = 0; k < dp.length; k++) {  
 dp[k] = 新数组(n);  
 }  
  
 for(让 i = 0; i < m; i++) {  
 for(让 j = 0; j < n; j++) {  
 如果(我 == 0 && j == 0){  
 dp[i][j] = 网格[i][j];  
 } 否则如果(我 == 0){  
 dp[i][j] = dp[i][j - 1] + 网格[i][j];  
 }否则如果(j == 0){  
 dp[i][j] = dp[i - 1][j] + 网格[i][j];  
 } 别的 {  
 dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];  
 }  
 }  
 }  
  
 返回 dp[m - 1][n - 1];  
 };

让我们空运行我们的算法 示例 2 .

 输入:grid = [[1, 2, 3], [4, 5, 6]]  
  
 第 1 步:m = grid.size()  
 = 2  
 n = 网格[0].size()  
 = 3  
  
 dp(2, 3)  
  
 第 2 步:循环 i = 0;我 < 米  
 0 < 2  
 真的  
  
 j = 0 的循环; j < n  
 0 < 3  
 真的  
  
 如果我 == 0 && j == 0  
 真的  
  
 dp[i][j] = 网格[i][j]  
 = 网格[0][0]  
 = 1  
  
 dp = [[1, 0, 0], [0, 0, 0]]  
  
 j++  
  
 j = 1  
 j < n  
 1 < 3  
 真的  
  
 如果我 == 0 && j == 0  
 真的  
 否则如果我 == 0  
 真的  
  
 dp[i][j] = dp[i][j - 1] + 网格[i][j]  
 = dp[0][1 - 1] + 网格[0][1]  
 = dp[0][0] + 网格[0][1]  
 = 1 + 2  
 = 3  
  
 dp = [[1, 3, 0], [0, 0, 0]]  
  
 j++  
 j < n  
 2 < 3  
 真的  
  
 如果我 == 0 && j == 0  
 真的  
 否则如果我 == 0  
 真的  
  
 dp[i][j] = dp[i][j - 1] + 网格[i][j]  
 = dp[0][2 - 1] + 网格[0][1]  
 = dp[0][1] + 网格[0][2]  
 = 3 + 3  
 = 6  
  
 dp = [[1, 3, 6], [0, 0, 0]]  
  
 j++  
 j < n  
 3 < 3  
 错误的  
  
 我++  
 我 = 1  
  
 第 3 步:循环 i < m  
 1 < 2  
 真的  
  
 j = 0 的循环; j < n  
 0 < 3  
 真的  
  
 如果我 == 0 && j == 0  
 错误的  
 否则如果我 == 0  
 错误的  
 否则如果 j == 0  
 真的  
  
 dp[i][j] = dp[i - 1][j] + 网格[i][j]  
 = dp[1 - 1][0] + 网格[1][0]  
 = dp[0][0] + 网格[1][0]  
 = 1 + 4  
 = 5  
  
 dp = [[1, 3, 6], [5, 0, 0]]  
  
 j++  
 j < n  
 1 < 3  
 真的  
  
 如果我 == 0 && j == 0  
 错误的  
 否则如果我 == 0  
 错误的  
 否则如果 j == 0  
 错误的  
 别的  
  
 dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + 网格[i][j]  
 = min(dp[1][1 - 1], dp[1 - 1][1]) + 网格[1][1]  
 = min(dp[1][0], dp[0][1]) + 5  
 = min(5, 3) + 5  
 = 3 + 5  
 = 8  
  
 dp = [[1, 3, 6], [5, 8, 0]]  
  
 j++  
 j < n  
 2 < 3  
 真的  
  
 如果我 == 0 && j == 0  
 错误的  
 否则如果我 == 0  
 错误的  
 否则如果 j == 0  
 错误的  
 别的  
  
 dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + 网格[i][j]  
 = min(dp[1][2 - 1], dp[1 - 1][2]) + 网格[1][2]  
 = min(dp[1][1], dp[0][2]) + 6  
 = min(8, 6) + 6  
 = 6 + 6  
 = 12  
  
 dp = [[1, 3, 6], [5, 8, 12]]  
  
  
 j++  
 j < n  
 3 < 3  
 错误的  
  
 我++  
 我 = 2  
  
 第 4 步:循环 i < m  
 2 < 2  
 错误的  
  
 第 5 步:返回 dp[m - 1][n - 1]  
 dp[2 - 1][3 - 1]  
 dp[1][2]  
 12  
  
 我们将答案返回为 12。

最初发表于 https://alkeshghorpade.me .

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/1356/49232905

标签:min,++,路径,网格,最小,int,grid,LeetCode,dp
来源: https://www.cnblogs.com/amboke/p/16634657.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有