Leetcode 剑指 Offer II 098.不同路径

题目难度: 中等

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

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

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

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

示例 1:

  • 输入:m = 3, n = 7
  • 输出:28

示例 2:

  • 输入:m = 3, n = 2
  • 输出:3
  • 解释:从左上角开始,总共有 3 条路径可以到达右下角。
    1. 向右 -> 向下 -> 向下
    2. 向下 -> 向下 -> 向右
    3. 向下 -> 向右 -> 向下

示例 3:

  • 输入:m = 7, n = 3
  • 输出:28

示例 4:

  • 输入:m = 3, n = 3
  • 输出:6

提示:

  • 1 <= m, n <= 100
  • 题目数据保证答案小于等于 2 * 10^9

题目思考

  1. 如何优化时间和空间复杂度?

解决方案

方法 1

  • 分析题目, 机器人只能向下或向右移动, 我们可以利用这一点, 累加当前坐标的左边和上边相邻坐标的路径数来得到当前坐标的路径数
  • 显然这就是动态规划的思路:
    • dp[r][c] 代表坐标(r,c)的路径数
    • 初始化 dp[0][0] = 1, 其他值全是 0, 表示开始时起点的路径数为 1
    • 然后进行状态转移: dp[r][c] = dp[r-1][c] + dp[r][c-1] (如果 r 或 c 为 0, 则相应的 r-1 或 c-1 的 dp 值就是 0, 只能从另一个方向转移而来)
    • 最终右下角坐标的 dp[m-1][n-1] 就代表总路径数
  • 下面的代码有详细的注释, 方便大家理解
复杂度
  • 时间复杂度 O(MN): 需要两重循环求 DP 值
  • 空间复杂度 O(MN): 二维 DP 数组的空间消耗
代码
class Solution:def uniquePaths(self, m: int, n: int) -> int:dp = [[0] * n for _ in range(m)]for r in range(m):for c in range(n):if (r, c) == (0, 0):# 起点dp值初始化为1dp[r][c] = 1else:# 左侧邻居路径数, 不存在时为0ldp = 0 if c == 0 else dp[r][c - 1]# 上侧邻居路径数, 不存在时为0udp = 0 if r == 0 else dp[r - 1][c]# 累加两个邻居的路径数dp[r][c] = ldp + udp# 最终结果就是右下角路径数return dp[m - 1][n - 1]

方法 2

  • 上面的 DP 做法固然可以解决这个问题, 那是否可以继续优化呢?
  • 答案是肯定的, 我们从另一个角度来思考这个问题, 机器人一共移动 m+n-2 次, 然后每次移动要么向下, 要么向右, 一共向下移动 m-1 次, 向右移动 n-1 次
  • 相当于从总移动次数 m+n-2 中选取 m-1 个, 我们可以利用数学求组合数的方法, 也即 C(m+n-2, m-1), 得到的值就是对应的总路径数
  • 这里可以额外进行一些优化, 使用 m 和 n 中的较小值来计算组合数, 对应的时间复杂度也是两者的较小值
  • 下面的代码有详细的注释, 方便大家理解
复杂度
  • 时间复杂度 O(min(M,N)): 求组合数时需要累乘 M-1 或 N-1 次, 取两者较小值
  • 空间复杂度 O(1): 没有使用额外变量
代码
class Solution:def uniquePaths(self, m: int, n: int) -> int:# 共有m+n-2次移动, 然后从中选择m-1次向下, 剩下n-1次向右# 所以总路径数就是组合数C(m+n-2,m-1) (也等于C(m+n-2,n-1))# 额外优化, 使用m和n的较小值来计算组合数mn = min(m, n)return math.comb(m + n - 2, mn - 1)

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华强北耳机最强攻略。华强北Airpods不踩坑,指南在这

#华强北Airpods##华强北耳机#这一篇文章&#xff0c;我会比较啰嗦&#xff0c;但会十分详细介绍目前能入手的渠道 和每一个渠道入手的优缺点&#xff0c;以便各位选择适合自己的渠道入手。 ■ 01 芯片ic大升级—————— 采用全新07IC板的洛达Ae芯片 整体提升三个单位算法 该…

idea-java序列化serialversionUID自动生成

&#x1f496;简介 java.io.Serializable 是 Java 中的一个标记接口&#xff08;marker interface&#xff09;&#xff0c;它没有任何方法或字段。当一个类实现了 Serializable 接口&#xff0c;那么这个类的对象就可以被序列化和反序列化。序列化是将对象的状态转换为字节流…

【原创】java+ssm+mysql小区物业管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

使用 Docker-compose 部署达梦 DM 数据库

目录 1. 获取达梦 DM8 Docker 镜像并上传到 Harbor 服务器 2. Docker-compose 部署达梦 DM8 数据库 3. 配置 dm.ini 文件 4.完整的 dm.ini 文件 最近&#xff0c;将 MySQL 数据库迁移到了达梦 DM8 数据库。本文将分享如何通过 Docker-compose 部署达梦 DM8 数据库的过程&am…

全面的编程语言常识

本文首发 编程语言常识 语雀看图区别编程语言什么是强类型、弱类型语言&#xff1f;哪种更好&#xff1f;强...https://www.yuque.com/ysgstudyhard/da6e0c/ggatoo 看图区别编程语言 什么是强类型、弱类型语言&#xff1f;哪种更好&#xff1f; 强类型语言 强类型语言是一…

网络通信与并发编程(二)基于tcp的套接字、基于udp的套接字、粘包现象

基于tcp的套接字 文章目录 基于tcp的套接字一、套接字的工作流程二、基于tcp的套接字通信三、基于udp的套接字通信四、粘包现象 一、套接字的工作流程 Socket是应用层与TCP/IP协议族通信的中间软件抽象层&#xff0c;它是一组接口。在设计模式中&#xff0c;Socket其实就是一个…

【Java】多线程 Start() 与 run() (简洁实操)

Java系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述start() 方法run() 方法 四、解决方案&#xff1a;4.1 重复调用 .run()4.2 重复调用 start()4.3 正常调用…

基础数据结构——链表(单向链表,双向链表,循环链表)

1.概述 在计算机科学中&#xff0c;链表是数据元素的线性集合&#xff0c;其每个元素都指向下一个元素&#xff0c;元素存储上并不连续 分类 单向链表&#xff0c;每个元素只知道其下一个元素是谁 双向链表&#xff0c;每个元素知道其上一个元素和下一个元素 循环链表&am…

EasyExcel填充模板导出excel.xlsx

菜鸟的自我救赎&#xff0c;自从有了GPT&#xff0c;还是头一次一个bug写一天。 直接贴导出excel模板的完整案例 官网冲刺 EasyExcel EasyExcel填充模板导出excel.xlsx / 导出excel模板 一、bug(不需要请跳过) 1.1 使用apache poi操作excel报错 java.lang.NoSuchMethodError…

与双指针的亲密接触:快与慢的浪漫交错

公主请阅 1.合并两个有序数组1.1 题目说明示例 1示例 2示例 3 1.2 题目分析 1.3代码部分1.4 代码解析 2.移动零2.1题目说明示例 1示例 2 2.2题目分析2.3代码部分2.4代码解析 1.合并两个有序数组 题目传送门 1.1 题目说明 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums…

汽车免拆诊断案例 | 2022款大众捷达VS5车行驶中挡位偶尔会锁在D3挡

故障现象  一辆2022款大众捷达VS5汽车&#xff0c;搭载EA211发动机和手自一体变速器&#xff0c;累计行驶里程约为4.5万km。该车行驶中挡位偶尔会锁在D3挡&#xff0c;车速最高约50 km/h&#xff0c;且组合仪表上的发动机故障灯和EPC灯异常点亮。 故障诊断  用故障检测仪检…

linux一二三章那些是重点呢

第一章 静态库动态库的区别 什么是库 库文件是计算机上的一类文件&#xff0c;可以简单的把库文件看成一种代码仓库&#xff0c;它提供给使用者一些可以直接 拿来用的变量、函数或类。 如何制作 静态动态库 静态库&#xff1a; GCC 进行链接时&#xff0c;会把静态库中代码打…

MySQL-15.DQL-分页查询

一.DQL-分页查询 -- 分页查询 -- 1. 从 起始索引0 开始查询员工数据&#xff0c;每页展示5条记录 select * from tb_emp limit 0,5; -- 2.查询 第1页 员工数据&#xff0c;每页展示5条记录 select * from tb_emp limit 0,5; -- 3.查询 第2页 员工数据&#xff0c;每页展示5条记…

Golang | Leetcode Golang题解之第491题非递减子序列

题目&#xff1a; 题解&#xff1a; var (temp []intans [][]int )func findSubsequences(nums []int) [][]int {ans [][]int{}dfs(0, math.MinInt32, nums)return ans }func dfs(cur, last int, nums []int) {if cur len(nums) {if len(temp) > 2 {t : make([]int, len(…

4.计算机网络_TCP

可靠与效率 TCP的主要特点&#xff1a; TCP是面向连接的运输层协议&#xff0c;每一条TCP连接只能有两个端点&#xff0c;即&#xff1a;点对点、一对一形式。每一个端口都是一个socket。TCP提供可靠交付的服务TCP提供全双工通信&#xff0c;因为TCP的收发缓冲区是分开的。TC…

java导出带图形的word

先看效果图&#xff1a;方法都是一样的&#xff0c;所以数据只做了前两组 第一步需要准备模版&#xff1a; 新建一个word插入图表&#xff0c;选择想要的图表。 编辑图表&#xff1a;营业额表示数字&#xff0c;季度表示文字。其他的样式编辑可根据自己的需求更改&#xff0c;…

(42)MATLAB中使用fftshift绘制以零为中心的功率谱

文章目录 前言一、MATLAB代码二、仿真结果画图 前言 在分析信号的频率分量时&#xff0c;将零频分量平移到频谱中心会很有帮助。本例给出绘制以零为中心的功率谱的方法。 一、MATLAB代码 代码如下&#xff1a; f 1; % 余弦波的振荡频率&#xf…

400行程序写一个实时操作系统(十):用面向对象思想构建抢占式内核

前言 通过前几章的学习&#xff0c;我们学会了如何为RTOS设计一个合理的内存管理算法。现在&#xff0c;是时候学习设计RTOS内核了。 关于RTOS内核的文章也有很多&#xff0c;但都有一点先射箭再化靶子的意味。要么是代码连篇解释却寥寥无几&#xff0c;要么是要先怎么样再怎么…

大数据linux操作系统

第一关&#xff1a;Linux的初体验 答案&#xff1a; cd / ls -a / &#xff08;里面有空格要注意&#xff09; 第二关&#xff1a;Linux的常用命令 答案&#xff1a; touch newfile mkdir newdir cp newfile newdir/newfileCpy 第三关&#xff1a;Linux查询命令帮助语句…

飞机大战告尾

参考 PPO算法逐行代码详解 链接 通过网盘分享的文件&#xff1a;PlaneWar 链接: https://pan.baidu.com/s/1cbLKTcBxL6Aem3WkyDtPzg?pwd1234 提取码: 1234 10.17关于博客发了又改这件事 悲催的事 今天训练了一早上ppo模型&#xff0c;满怀期待的检测成果时发现一点长进都…