【面试经典150 | 动态规划】不同路径 II

文章目录

  • 写在前面
  • Tag
  • 题目1
    • 方法一:动态规划
    • 方法二:空间优化
  • 题目2
    • 方法一:动态规划+空间优化
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【动态规划-空间优化】【网格】


题目1

62. 不同路径


方法一:动态规划

本题是解题思路与 【面试经典150 | 动态规划】最小路径和 类似。

定义状态

定义 f[i][j] 表示机器人从网格左上角 (0, 0) 到位置 (i, j) 可以行走的不同位置数量。

转移关系

根据 “机器人每次只能向下或者向右移动一步”,可知到达 (i, j) 位置可以从 (i-1, j)(i, j-1) 行走到达,于是有转移关系:

f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i ] [ j − 1 ] f[i][j] = f[i-1][j] + f[i][j-1] f[i][j]=f[i1][j]+f[i][j1]

base case

因为 “机器人每次只能向下或者向右移动一步”,所以机器人从 (0, 0) 位置到第 0 行、第 0 列的不同路径数均为 1。

最后返回

最后返回 f[m-1][n-1],表示机器人从网格左上角 (0, 0) 到网格右下角 (m-1, n-1) 可以行走的不同路径数量。

实现代码

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> f(m, vector<int>(n));for (int i = 0; i < m; ++i) {f[i][0] = 1;}for (int j = 0; j < n; ++j) {f[0][j] = 1;}for (int i = 1; i < m; ++i) {for (int j = 1; j < n; ++j) {f[i][j] = f[i - 1][j] + f[i][j - 1];}}return f[m - 1][n - 1];}
};

复杂度分析

时间复杂度: O ( m n ) O(mn) O(mn) m m m 为网格的行数, n n n 为网格的列数。

空间复杂度: O ( m n ) O(mn) O(mn)

方法二:空间优化

仿照 【面试经典150 | 动态规划】最小路径和 中空间优化的思想,可以对朴素的动态规划法进行类似的空间优化。具体实现见代码。

实现代码

class Solution {
public:int uniquePaths(int m, int n) {int more = max(m, n);int less = min(m, n);vector<int> f(less, 1);for (int i = 1; i < more; ++i) {for (int j = 1; j < less; ++j) {/*f[j] = f[j] + f[j-1] 第二个f[j] 表示从上一行向下到达位置(i,j)f[j-1] 表示从上一列向右到达位置(i,j)*/ f[j] += f[j-1];         }}return f[less-1];}
};

复杂度分析

时间复杂度: O ( m n ) O(mn) O(mn) m m m 为网格的行数, n n n 为网格的列数。

空间复杂度: O ( m i n { m , n } ) O(min\{m,n\}) O(min{m,n})

题目2

63. 不同路径 II


方法一:动态规划+空间优化

对比上一个题目,本题增加了障碍物,解法上与上题基本一致。但是有几处变动:

  • 遇到障碍物时 f [ i ] [ j ] = 0 f[i][j]=0 f[i][j]=0
  • 本题只需要考虑没有遇到障碍物即 o b s t a c l e G r i d [ i ] [ j ] ! = 1 obstacleGrid[i][j] != 1 obstacleGrid[i][j]!=1 时的不同路径数的问题,此时的状态转移方程也和上题一致。

朴素的动态规划方法

直接给出朴素的动态规划解法。

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size(), n = obstacleGrid[0].size();vector<vector<int>> f(m, vector<int>(n));f[0][0] = obstacleGrid[0][0] == 1 ? 0 : 1;// 初始化第 0 行for(int j = 1; j < n; ++j) {if (obstacleGrid[0][j] != 1) {f[0][j] = f[0][j-1];}}// 初始化第 0 列for (int i = 1; i < m; ++i) {if (obstacleGrid[i][0] != 1) {f[i][0] = f[i-1][0];}}// 计算一般位置for (int i = 1; i < m; ++i) {for(int j = 1; j < n; ++j) {if (obstacleGrid[i][j] != 1) {f[i][j] = f[i-1][j] + f[i][j-1];}}}return f[m-1][n-1];}
};

空间优化

先贴出代码

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m = obstacleGrid.size(), n = obstacleGrid[0].size();int more = max(m, n), less = min(m, n);bool rowMore = (more == m);vector<int> f(less);f[0] = (obstacleGrid[0][0] == 0);for (int i = 0; i < more; ++i) {for (int j = 0; j < less; ++j) {if ((rowMore && obstacleGrid[i][j] == 1) || (!rowMore && obstacleGrid[j][i] == 1)) {f[j] = 0;continue;}if ((rowMore && j-1 >= 0 && obstacleGrid[i][j-1] == 0) || (!rowMore && j-1 >= 0 && obstacleGrid[j-1][i] == 0)) {f[j] += f[j-1];}}}return f[less-1];}
};

我们使用布尔变量 rowMore 来表示网格的行数是都大于列数:

  • 如果行数大于等于列数,则有 rowMore =true,此时按行更新 f;如果 (i, j) 位置有障碍物则更新 f[j] = 0;如果前一列的位置没有障碍物,则可以从前一列到达本列,更新 f[j] = f[j] + f[j-1],其中第二个 f[j] 表示上一行的位置 (i-1, j) 的不同路径数。
  • 如果行数小于列数,则有 rowMore =false,此时按列更新 f;如果 (j, i) 位置有障碍物则更新 f[j] = 0;如果前一行的位置没有障碍物,则可以从前一行到达本行更新 f[j] = f[j] + f[j-1],其中第二个 f[j] 表示上一列的位置 (j, i-1) 的不同路径数。
  • 可能会有点绕,读者还需多多阅读体会。如果实现想不明白,可以直接按照行来更新 f,这样空间复杂度为 O ( n ) O(n) O(n)

复杂度分析

时间复杂度: O ( m n ) O(mn) O(mn) m m m 为网格的行数, n n n 为网格的列数。

空间复杂的:经过空间优化后的空间复杂度为 O ( m i n { m , n } ) O(min\{m,n\}) O(min{m,n})。朴素动态规划的时间复杂度为 O ( m n ) O(mn) O(mn)


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。

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

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

相关文章

跟着Kimi Chat学习提示工程Prompt Engineering!让AI更高效地给你打工!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

DTFT及其反变换的直观理解

对于离散时间傅里叶变换(DTFT)及其反变换的讲解&#xff0c;教材里通常会先给出DTFT正变换的公式&#xff0c;再举个DTFT的简单变换例子&#xff0c;推导一下DTFT的性质&#xff0c;然后给出DTFT反变换的公式&#xff0c;再证明一下正变换和反变化的对应关系。总的来说就是&…

conda修改默认安装python版本为指定版本

1.查看conda中当前的python版本号: 打开Anaconda Powershell Prompt 输入python -V 回车会输出版本号 2.查看conda所支持的python版本,并选择指定版本安装 选择一个3.9.13版本的进行安装 安装命令: conda install python=3.9.13 如果一直卡在这个画面,请使用管理员权限运行…

python ---- %r %s格式输出的区别

在python中&#xff0c; % s和 % r是我们常用的格式符&#xff0c;它们的用法基本一致&#xff0c;但作用却不尽相同&#xff0c;下面简要说明一下两者的区别&#xff1a; 1. % s是将对象 / 变量传递到str()方法中&#xff0c;并将其转化为面向用户的可阅读的格式。 2. % r是将…

聊一聊单点登录

互联网工程师 一、单点登录的概念 单点登录&#xff08;Single Sign-On&#xff0c;简称SSO&#xff09;是一种身份认证和授权技术&#xff0c;旨在解决用户在访问多个应用系统时需要重复登录的问题。该技术允许用户在一个应用系统中完成登录后&#xff0c;就可以访问其他相互信…

C#,简单,精巧,实用的按类型删除指定文件的工具软件

点击下载本文软件&#xff08;积分&#xff09;&#xff1a; https://download.csdn.net/download/beijinghorn/89059141https://download.csdn.net/download/beijinghorn/89059141 下载审核通过之前&#xff0c;请从百度网盘下载&#xff08;无积分&#xff09;&#xff1a;…

web框架的本质初识

1.什么是HTML HTML是一个超文本语言&#xff0c;是一种创建网页结构的标记语言。就是你女朋友化妆之后的样子 2.什么是HTTP协议 是一种用于在Web上传输数据的协议。它是客户端和服务器之间进行相互通信的基础的协议 3.HTTP的特点 无连接&#xff1a;每个http请求都是独立的…

母婴商品销售数据分析-Python数据分析项目

文章目录 母婴商品销售数据分析项目介绍项目背景分析目的 数据准备导入数据数据清洗 数据分析整体市场情况第一季度销量下滑原因第四季度销量上升原因复购率 商品销售情况 母婴商品销售数据分析 项目介绍 项目背景 政策Politics&#xff1a;国家发展改革委2013年5月28日表示…

【学习笔记】java项目—苍穹外卖day10

文章目录 苍穹外卖-day10课程内容1. Spring Task1.1 介绍1.2 cron表达式1.3 入门案例1.3.1 Spring Task使用步骤1.3.2 代码开发1.3.3 功能测试 2.订单状态定时处理2.1 需求分析2.2 代码开发2.3 功能测试 3. WebSocket3.1 介绍3.2 入门案例3.2.1 案例分析3.2.2 代码开发3.2.3 功…

RIP协议(路由信息协议)

一、RIP协议概述 RIP协议&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;即根据跳数来度量路由开销&#xff0c;进行路由选择。 相比于其它路由协议&#xff08;如OSPF、ISIS等&#xff09;&#…

好物视频素材怎么找?推荐8个视频素材库大全高清素材

在这个故事无处不在的时代&#xff0c;找到那些能够让你的视频内容脱颖而出的高清无水印素材&#xff0c;就像是探寻宝藏。为了让你的每一帧都充满力量和情感&#xff0c;下面介绍的八个视频素材网站覆盖了从传统风格到现代节奏的各种需求&#xff0c;帮助你在全球范围内寻找到…

uniapp 设置globalStyle navigationBarTitleText 不显示

设置全局的navigationBarTitleText但是没有显示 没效果: 原因: 这里实际上设置了navigationBarTitleText 为"" 所以不会使用全局的设置 解决方法就是直接将这一行代码删除