Python面试宝典第19题:最小路径和

news2024/9/22 1:16:07

题目

        给定一个包含非负整数的m x n网格grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。

        示例 1:

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

        示例 2:

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

记忆化递归法

        记忆化递归法的核心思想是将递归过程中遇到的子问题及其解存储起来,即记忆化,以便在后续遇到相同子问题时直接查表获取结果,避免重复计算。针对本题,我们将使用一个二维数组memo来存储到达每个格子的最小路径和。使用记忆化递归法求解本题的主要步骤如下。

        1、初始化记忆数组。创建一个与原网格大小相同的二维数组memo,全部初始化为一个特殊值(如None或极大值),表示尚未计算。

        2、定义递归函数。编写一个递归函数,输入参数为当前坐标(i, j),该函数计算从(i, j)到右下角的最小路径和。递归的基本情况是当(i, j)位于右下角时,直接返回该格子的值。

        3、记忆化处理。在递归函数内部,首先检查memo[i][j]是否已被计算过,若已计算则直接返回该值。

        4、递归计算。否则,计算最小路径和,即分别计算从当前位置向下和向右移动的最小路径和,取二者中较小者加上当前位置的值。

        5、更新记忆数组。将计算出的最小路径和存入memo[i][j]。

        6、调用递归函数。从起点(0, 0)开始,调用递归函数。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def minimum_path_sum_by_recursion(grid):
    def helper(i, j):
        # 基本情况:到达右下角
        if i == m - 1 and j == n - 1:
            return grid[i][j]
        
        # 已经计算过的情况,直接返回结果
        if memo[i][j] is not None:
            return memo[i][j]
        
        # 向下或向右移动的最小路径和
        if i < m - 1 and j < n - 1:
            memo[i][j] = grid[i][j] + min(helper(i+1, j), helper(i, j+1))
        elif i < m - 1:
            # 只能向下
            memo[i][j] = grid[i][j] + helper(i+1, j)
        else:
            # 只能向右
            memo[i][j] = grid[i][j] + helper(i, j+1)
        
        return memo[i][j]
    
    if not grid or not grid[0]:
        return 0

    m, n = len(grid), len(grid[0])
    # 初始化记忆数组
    memo = [[None]*n for _ in range(m)]
    # 从起点开始调用递归函数
    return helper(0, 0)

grid = [[1, 3, 1], [1, 5, 1], [4, 2, 1]]
print(minimum_path_sum_by_recursion(grid))

grid = [[1, 2, 3], [4, 5, 6]]
print(minimum_path_sum_by_recursion(grid))

动态规划法

        动态规划法的核心思想在于解决具有重叠子问题和最优子结构的问题。对于本题,我们要找的是从左上角到右下角的最小路径和。每一步只能向右或向下移动,这意味着到达任何一个格子的最小路径和,都是从其左边或上边的格子通过一步移动过来的最小路径和加上当前格子的值。因此,我们可以从左上角开始,逐步构建一个二维数组来存储到达每个格子的最小路径和。使用动态规划法求解本题的主要步骤如下。

        1、初始化。创建一个与原网格相同大小的二维数组dp,其中dp[0][0] = grid[0][0],表示起点的最小路径和就是它本身的值。

        2、边界条件。对于第一行的所有单元格,其最小路径和等于从上一列的相应单元格移动下来的值加上当前单元格的值。同理,第一列的所有单元格也是如此处理。

        3、状态转移方程。对于dp[i][j](其中i>0且j>0),其值应为min(dp[i-1][j], dp[i][j-1]) + grid[i][j],即到达当前格子的最小路径和等于其上方格子和左侧格子的最小路径和中的较小者,再加上当前格子的值。

        4、最终结果。dp[m-1][n-1]即为从左上角到右下角的最小路径和。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def minimum_path_sum_by_dp(grid):
    if not grid or not grid[0]:
        return 0
    
    m, n = len(grid), len(grid[0])
    # 初始化dp数组
    dp = [[0]*n for _ in range(m)]
    
    # 初始化dp数组的第一行和第一列
    dp[0][0] = grid[0][0]
    for i in range(1, m):
        dp[i][0] = dp[i-1][0] + grid[i][0]
    for j in range(1, n):
        dp[0][j] = dp[0][j-1] + grid[0][j]
    
    # 根据状态转移方程填充dp数组
    for i in range(1, m):
        for j in range(1, n):
            dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
    
    return dp[m-1][n-1]

grid = [[1, 3, 1], [1, 5, 1], [4, 2, 1]]
print(minimum_path_sum_by_dp(grid))

grid = [[1, 2, 3], [4, 5, 6]]
print(minimum_path_sum_by_dp(grid))

总结

        记忆化递归法和动态规划法的时间复杂度均为O(m*n),其中m和n分别是网格的行数和列数。这是因为,每个单元格最多被访问一次。两者的空间复杂度也一样,均为O(m*n), 需要一个与原网格大小相同的二维数组来存储中间结果。

        动态规划法还可以通过使用一维数组(滚动数组)来优化空间复杂度至 O(n)。这是因为,每一行的计算只需要前一行的信息,而不需要保留整个二维数组。对于每行,我们只需维护一个长度为n的一维数组。这样在计算完一行后,可以复用该数组空间来存储下一行的计算结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947106.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【帆软报表开发】决策系统挂载报表

登陆决策系统 点击服务器->报表平台管理登陆或者输入网址http://IP:端口号/webroot/decision登陆&#xff08;默认端口号&#xff1a;8075&#xff09; 第一次需要输入超级管理员的用户名和密码&#xff0c;然后登陆决策系统 成功登陆决策系统 报表模板所在位置 制作好的报…

PHP安全编程宝典:30000字精细解析

文章目录 基础语法单双引号的区别前后端分离数据类型PHP常量函数var_dump函数count函数print_r函数**readfile&#xff08;&#xff09;函数****file_get_contents()函数****file_put_contents()函数**header函数fopen函数fread 函数rename函数copy&#xff08;&#xff09;函数…

生活实用英语口语“拆迁”用英文怎么说?柯桥成人学英语到蓝天广场

● 1. “拆迁”英语怎么说&#xff1f; ● 01. 其实国外也有拆迁 但国外的拆迁&#xff0c;只管拆 不管安置&#xff0c;你爱去哪去哪 英文可以说 housing removal 02. 但我们中国的“拆迁” 既管“拆”也管“迁” &#xff08;还是中国人幸福~&#xff09; 英文可以说 housin…

C语言 ——— 函数指针的定义 函数指针的使用

目录 何为函数指针 打印 函数名的地址 及 &函数名的地址 函数指针的代码&#xff08;如何正确存储函数地址&#xff09; 函数指针的使用 何为函数指针 类比&#xff1a; 整型指针 - 指向整型数据的指针&#xff0c;整型指针存放的是整型数据的地址 字符指针 - 指向字…

视觉语言动作模型:从网页知识到机器人控制的实战RT-2

作者&#xff1a; Anthony Brohan, Noah Brown, Justice Carbajal, Yevgen Chebotar, Xi Chen, Krzysztof Choromanski, Tianli Ding, Danny Driess, Avinava Dubey, Chelsea Finn, Pete Florence, Chuyuan Fu, Montse Gonzalez Arenas, Keerthana Gopalakrishnan, Kehang Han…

等级保护 总结2

网络安全等级保护解决方案的主打产品&#xff1a; HiSec Insight安全态势感知系统、 FireHunter6000沙箱、 SecoManager安全控制器、 HiSecEngine USG系列防火墙和HiSecEngine AntiDDoS防御系统。 华为HiSec Insight安全态势感知系统是基于商用大数据平台FusionInsight的A…

VMware 17.5.2 下载安装教程

迅雷&#xff1a; 分享文件&#xff1a;VMware17.5.2 链接&#xff1a;https://pan.xunlei.com/s/VO2YWzmIoNXXUziaESHVX2OrA1?pwdhbqh# 百度网盘&#xff1a; 链接: https://pan.baidu.com/s/18iexDwJAec9OkATYnfUlSg?pwd8888 提取码: 8888 1.双击安装包运行 2.若出现以…

《软件导刊》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《软件导刊》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《软件导刊》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;湖北省科学技术厅 主办单位&#xff1a;湖北…

Redisson分布式锁使用详解

引言 日常开发中&#xff0c;难免遇到一些并发的场景&#xff0c;为了保证接口执行的一致性&#xff0c;通常采用加锁的方式&#xff0c;因为服务是分布式部署模式&#xff0c;本地锁Reentrantlock和Synchnorized这些就先放到一边了&#xff0c;Redis的setnx锁存在无法抱保证原…

VBA技术资料MF178:将某个文件夹中的图片导入Word

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

敏捷开发笔记(第13章节)--COMMAND模式和ACTIVE OBJECT模式

1&#xff1a;PDF上传链接 【免费】敏捷软件开发(原则模式与实践)资源-CSDN文库 没有人天生就具有命令他人的权利。 --Denis Diderot&#xff08;1713一1784&#xff0c;法国哲学家&#xff0c;百料全书编者) 在近几…

20240724----安装git和配置git的环境变量/如何用命令git项目到本地idea

备注参考博客&#xff1a; 1&#xff09;可以参考博客&#xff0c;用git把项目git到本地 2&#xff09;可以参考博客vcs没有git 3)git版本更新&#xff0c;覆盖安装 &#xff08;一&#xff09;安装git &#xff08;1&#xff09;官网下载的链接 https://git-scm.com/downlo…

【轨物方案】新型储能管理系统(EMS)解决方案

储能EMS作为储能系统的大脑&#xff0c;其重要性不言而喻&#xff0c;但是随着储能行业的不断扩大以及对应产品的不断升级&#xff0c;其对应的售后运维变得越来越复杂&#xff0c;储能系统急需配备完善的EMS系统来监控和优化自身的运营状态&#xff0c;同时满足售后运维&#…

LeetCode 热题 HOT 100 (010/100)【宇宙最简单版】

【链表】No. 0206 反转链表 【简单】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xf…

Docker-Compose配置zookeeper+KaFka+CMAK简单集群

1. 本地DNS解析管理 # 编辑hosts文件 sudo nano /etc/hosts # 添加以下三个主机IP 192.168.186.77 zoo1 k1 192.168.186.18 zoo2 k2 192.168.186.216 zoo3 k3注&#xff1a;zoo1是192.168.186.77的别名&#xff0c;zoo2是192.168.186.18的别名&#xff0c;zoo3是192.168.186.1…

JavaScript(14)——DOM

Web API 作用&#xff1a;就是使用JS去操作html和浏览器 分类&#xff1a;DOM&#xff08;文档对象模型&#xff09;、BOM&#xff08;浏览器对象模型&#xff09; DOM DOM是用来呈现以及与任意HTML或XML文档交互的API&#xff0c;简单来说就是操作网页的内容。 DOM树 将H…

Ansible的脚本-----playbook剧本【下】

目录 实战演练六&#xff1a;tags 模块 实战演练七&#xff1a;Templates 模块 实战演练六&#xff1a;tags 模块 可以在一个playbook中为某个或某些任务定义“标签”&#xff0c;在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。 playboo…

secureCRT同时在所有已打开窗口执行命令、mac-os下使用的SecureCRT版本 以及 SecureCRT一段时间不操作没有响应的问题

一、secureCRT命令行工具一次性同时在所有已打开窗口执行命令 公司的服务器比较多&#xff0c;最近因为opcache&#xff0c;上线发布后&#xff0c;需要重启所有的WEB服务器上的php。目前使用的jenkins发布&#xff0c;不过账号安全问题&#xff0c;给jenkins的账号权限受限不能…

【BUG】已解决:IndexError: positional indexers are out-of-bounds

IndexError: positional indexers are out-of-bounds 目录 IndexError: positional indexers are out-of-bounds 【常见模块错误】 【解决方案】 原因分析 解决方法 示例代码 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博…

golang常用的一些 strings函数

1.判断字符串是否包含另一个字符串 strings.Contains str : "exported_provider_example"prefix : "exported_provider"if strings.Contains(str, prefix) {fmt.Println("字符串包含 exported_provider")} else {fmt.Println("字符串不包含…