当前位置: 首页 > news >正文

代码随想录算法训练营第三十三天 | 62.不同路径 63.不同路径

LeetCode 62.不同路径:

文章链接
题目链接:62.不同路径

思路:

  1. 动态规划
    使用二维数组保存递推结果
    ① dp数组及下标含义
    dp[i][j]:表明从(0, 0)到下标为(i, j)的点有多少条不同的路径
    ② 递推式:
    机器人只能向下或向右移动,因此dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
    ③ 初始化:
    应当初始化第一行和第一列均为1
for i in range(m)	dp[i][0] = 0	# 第一列
for i in range(n) dp[0][i] = 0	# 第一列

④ 遍历方式:
从左到右,从上往下遍历
⑤ 举例推导
在这里插入图片描述

class Solution:def uniquePaths(self, m: int, n: int) -> int:if m == 1 and n == 1:return 1dp = [[1] * n for _ in range(m)]    # 第一行和第一列路径数都为1dp[0][0] = 1    # 出发点路径数为1for i in range(1, m):for j in range(1, n):dp[i][j] = dp[i - 1][j] + dp[i][j - 1]return dp[m - 1][n - 1]

dp数组可以简单为一维数组
按照从左到右,从上到下的遍历顺序
原dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
因此可以简化为一维数组。其中新dp[j]保存的是原dp[i - 1][j]
相当于dp[j]保存的是上一行的数据,从而dp[j] = dp[j] + dp[j - 1]

class Solution:def uniquePaths(self, m: int, n: int) -> int:if m == 1 and n == 1:return 1dp = [1] * nfor i in range(1, m):for j in range(1, n):dp[j] += dp[j - 1]return dp[n - 1]
  1. 数论的方法
    从(0, 0)到(m - 1, n - 1)一共 m + n - 2步,其中m - 1步为向下的。因此只要在m + n - 2中选择 m - 1步向下即可,即求组合C_{m + n - 2} ^ {m - 1}
    不能直接分别计算分子、分母后进行除法运算,会溢出,因此需要一边求分子一边对分子进行除法运算
class Solution:def uniquePaths(self, m: int, n: int) -> int:if m == 1 and n == 1:return 1numerator = 1   # 分子denominator = m - 1     # 分母t = m + n - 2count = m - 1while count:numerator *= twhile denominator != 0 and numerator % denominator == 0:numerator = numerator // denominatordenominator -= 1t -= 1count -= 1return numerator

感悟:

简化dp数组以及使用数论的方法求


LeetCode 63.不同路径Ⅱ:

文章链接
题目链接:63.不同路径Ⅱ

思路:

  1. 使用二维数组保存递推的结果
    ① dp数组及下标的含义:
    dp[i][j]:表示从(0, 0)到(i, j)的移动路径中没有障碍的路径数
    ② 递推式:
    机器人还是只能向下或向右移动,因此
    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
    但是要求路径中不能有障碍,因此上式只能在(i, j)不为障碍时成立
    ③ 初始化:
    还是初始化横向和纵向的,但是遇到障碍后,后面的dp应当都为0
    在这里插入图片描述
    1)第一种初始化
    dp[i][0] = dp[i - 1]0
dp[0][0] = 1
# 初始化第1列,行同理
for i in range(1, m):if obstacleGrid[i][0] == 0:dp[i][0] = dp[i - 1][0]else:dp[i][0] = 0

2)第二种初始化。
dp最开始时初始化为全0,遍历第1列时,遇到非障碍赋值为1,遇到障碍直接退出

dp = [[0] * n for _ in range(m)]
dp[0][0]
for i in range(1, m):if obstacleGrid[i][0] == 0:dp[i][0] = 1else:break 

④ 遍历方式
从左到右,从上到下
⑤ 举例
在这里插入图片描述
需要注意的是,初始化遍历时,第一种遍历方式dp[0][0] = 1,但是出发点是会有障碍的,因此需要先判断出发点是否有障碍再下一步初始化

class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:if obstacleGrid[0][0] == 1: # 初始位置就有障碍return 0m, n = len(obstacleGrid), len(obstacleGrid[0])dp = [[0] * n for _ in range(m)]    # 初始化为0dp[0][0] = 1# 初始化,遇到有障碍物之后的路径数均为0for i in range(1, m):  # 第0列if obstacleGrid[i][0] == 0:dp[i][0] = dp[i - 1][0]for j in range(1, n):  # 第0行if obstacleGrid[0][j] == 0:dp[0][j] = dp[0][j - 1]# 递推for i in range(1, m):for j in range(1, n):if obstacleGrid[i][j] == 0:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]return dp[m - 1][n - 1]
  1. 使用一维数组保存递推的结果
    如果使用一维数组保存递推的结果,实际上一维数组保存的是原二维dp数组中上一行的结果,即一维数组的遍历是按行来的。
    初始化:和二维数组初始化方式相同,但是只初始化第1行
    递推:按行递推遍历时,j从0开始,因为一维数组保存的是原二维数组上一行的结果,因此dp[j] = dp[j] + dp[j - 1]仅在j != 0时成立, j = 0时,dp[j]直接继承上一行的结果不变
class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:if obstacleGrid[0][0] == 1:return 0m, n = len(obstacleGrid), len(obstacleGrid[0])dp = [0] * ndp[0] = 1for j in range(1, n):if obstacleGrid[0][j] == 0:dp[j] = 1else:breakfor i in range(1, m):for j in range(n):if obstacleGrid[i][j] == 1:dp[j] = 0elif j != 0:dp[j] += dp[j - 1]return dp[n - 1] 

感悟:

将二维dp数组降为一维dp数组


学习收获:

有障碍时对应的dp数组如何初始化,以及递推式如何变化。
以及将原本的二维dp数组降为一维dp数组时,遍历的话 j 从0开始

相关文章:

代码随想录算法训练营第三十三天 | 62.不同路径 63.不同路径

LeetCode 62.不同路径: 文章链接 题目链接:62.不同路径 思路: 动态规划 使用二维数组保存递推结果 ① dp数组及下标含义 dp[i][j]:表明从(0, 0)到下标为(i, j)的点有多少条不同的路径 ② 递推式: 机器人只能向下或向…...

使用Flask构建RESTful API

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Flask构建RESTful API Flask简介 环境搭建 安装Flask 项目结构 创建应用 路由定义 请求处理 获取查询参数 获取请求体 响应…...

基于springboot的Java学习论坛平台

基于springboot的Java学习论坛平台 摘 要 在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括学习平台的网络应用,在外国学习平台已经是很普遍的方式,不过国内的管理平台可能还处于起步阶段。学习平台具…...

Python离线环境搭建

引言 在软件开发过程中,我们常常会遇到内网环境无法直接访问外网的情况,这就需要我们通过一些特殊手段来搭建Python开发环境。本文将详细介绍如何利用U盘在内网机与外网机之间迁移Python环境及其依赖包。 工具准备 1台内网机1台外网机1个U盘 操作步骤…...

windows下kafka使用出现的问题

kafka启动 启动kafka需要先启动zookeeper,在kafka根目录下先启动zookeeper .\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties启动kafka 另开一个cmd命令行 .\bin\windows\kafka-server-start.bat .\config\server.propertieskafka与jdk版…...

ctfshow文件包含web78~81

目录 web78 方法一:filter伪协议 方法二:input协议 方法三:data协议 web79 方法一:input协议 方法二:data协议 web80 方法一:input协议 方法二:日志包含getshell web81 web78 if(isset($_GET[file]…...

鸿蒙生态认识

好的,让我们更深入地探讨鸿蒙生态的发展机遇、面临的挑战,以及未来的潜力。 对鸿蒙生态的认知与分析 鸿蒙系统作为一种新兴的操作系统,旨在打破设备之间的壁垒,打造一个更加连通的生态环境。以下是对其崛起的进一步分析&#xf…...

Hadoop-004-Big Data Tools插件的使用

一、Big Data Tools插件配置流程 1、安装Big Data Tools插件 以IntelliJ IDEA 2024.2.3为例打开setting, 搜索安装Big Data Tools插件后重启IDEA 2、Windows系统基础配置 Windows系统需要做一些基础设置,配合插件使用,将之前下载的hadoop-3.2.4.tar.gz 解压到D…...

linux8在线扩容/home目录

虚机新增1T磁盘 [rootrsb ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 8.8 (Ootpa) [rootrsb ~]# vgs VG #PV #LV #SN Attr VSize VFree ol 2 3 0 wz--n- <2.00t 0 [rootrsb ~]# lvs LV VG Attr LSize Pool Origin Dat…...

【C/C++】模拟实现strcpy

学习目标&#xff1a; 使用代码模拟实现strcpy。 逻辑&#xff1a; strcpy 函数的返回类型是 void 即不返回数据。strcpy 函数的参数类型是 char* &#xff0c;用于接收数组。strcpy 函数要把一个数组复制到另一个数组。 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS …...

网络编程番外——IO多路复用的应用说明

一、IO多路复用与多线程 IO多路复用&#xff0c;IO Multiplexing&#xff0c;其实就是在IO上进行监听处理导致线程被阻塞&#xff08;如果非阻塞就必须不断的轮询&#xff0c;仍然是占用此线程&#xff09;&#xff0c;如果一个IO对应一个线程是不是太浪费了。而且在诸如网络I…...

【Java爬虫的淘宝寻宝记】—— 淘宝商品类目的“藏宝图”

引言&#xff1a; 在淘宝这个广袤的“商品宇宙”中&#xff0c;每一件商品都是一颗璀璨的星球&#xff0c;而商品类目就是连接这些星球的星际航道。今天&#xff0c;我们将派遣一位勇敢的Java爬虫宇航员&#xff0c;去揭开这些星际航道背后的秘密——商品类目。准备好了吗&…...

探索Python文档自动化的奥秘:揭开docxtpl库的神秘面纱

文章目录 探索Python文档自动化的奥秘&#xff1a;揭开docxtpl库的神秘面纱1. 背景介绍2. 库简介3. 安装指南4. 基础函数介绍5. 实际应用场景6. 常见问题及解决方案7. 总结 探索Python文档自动化的奥秘&#xff1a;揭开docxtpl库的神秘面纱 1. 背景介绍 在日常工作中&#xf…...

RabbitMQ的解耦、异步、削峰是什么?

RabbitMQ在分布式系统和微服务架构中起到了重要的作用&#xff0c;其特性可以实现解耦、异步以及削峰&#xff0c;下面是对这三个概念的详细解释&#xff1a; 1. 解耦 解耦是指使系统的不同组件间的依赖关系减少或消失。在使用RabbitMQ时&#xff0c;生产者&#xff08;发送消…...

4:arm汇编语言4:bits/byte的介绍(ASCII码)与二进制补位

4.2 bits/byte的介绍与ASCII码的引入 这个是详细介绍计算机内部原理的基础&#xff0c;bits与byte其实这两个是计算机中非常重要的单位。首先看一下bits&#xff0c;它是一个基础的计算机单位。计算机单位&#xff1f;像长度单位是米&#xff0c;体重的单位是kg&#xff0c;你…...

C++实现仿安卓线程Handler、Message、Looper的功能

在java开发中&#xff0c;习惯使用Handler、Message来处理同步&#xff0c;比如对相机的操作(open、setParamters、start、stop、clost)全部抛到同一个线程处理&#xff0c;防止并发操作导致异常&#xff0c;这样保留给外部的统一接口就是安全的&#xff0c;无论外部哪些线程来…...

构建安全的用户登录API:从请求验证到JWT令牌生成

构建安全的用户登录API&#xff1a;从请求验证到JWT令牌生成 为了实现这个后端POST /api/users/login端点&#xff0c;我们可以使用Node.js和Express框架&#xff0c;并结合一些常用的库如jsonwebtoken、bcrypt和express-validator来处理验证和密码校验。下面是一个完整的示例…...

状态模式:封装对象状态并改变行为的设计模式

1. 引言 在软件开发中&#xff0c;某些对象的行为会随着其内部状态的变化而变化。传统的实现方式可能需要使用大量的条件语句&#xff0c;导致代码复杂且难以维护。状态模式&#xff08;State Pattern&#xff09;提供了一种有效的方法&#xff0c;通过将状态行为封装在状态类…...

备战“双11”丨AI+物流:你的快递会有什么变化?

背景 在中国&#xff0c;每天有数以亿计的包裹在运输&#xff0c;尤其在电商促销季如“双十一”、“618”期间&#xff0c;快递量更是激增。快递物流行业面临人员短缺、配送效率低下和物流承载能力有限等问题。快瞳科技提供的AI识别解决方案通过智能化手段提高工作效率和配送准…...

理解为什么要有C++设计模式

什么时设计模式&#xff1f; 每一个模式描述了一个在我们周围不断重复的问题以及该问题的解决方案的核心&#xff0c;这样&#xff0c;就能一次有一次地使用该方案&#xff0c;而不必做重复劳动。 如何解决复杂性&#xff1f; 分解&#xff1a;人们面对复杂性有一个常见的做法…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...