LeetCode-hot100题解—Day6

原题链接:力扣热题-HOT100
我把刷题的顺序调整了一下,所以可以根据题号进行参考,题号和力扣上时对应的,那么接下来就开始刷题之旅吧~
1-8题见LeetCode-hot100题解—Day1
9-16题见LeetCode-hot100题解—Day2
17-24题见LeetCode-hot100题解—Day3
25-34题见LeetCode-hot100题解—Day4
39-56题见LeetCode-hot100题解—Day5
注:需要补充的是,如果对于每题的思路不是很理解,可以点击链接查看视频讲解,是我在B站发现的一个宝藏UP主,视频讲解很清晰(UP主用的是C++),可以结合视频参考本文的java代码。

力扣hot100题解 62-71

    • 62.不同路径
    • 63.不同路径Ⅱ
    • 64.最小路径和
    • 66.加一
    • 67.二进制求和
    • 69.x的平方根
    • 70.爬楼梯
    • 71.简化路径

62.不同路径

思路
本题采用动态规划来求解,最后需要得到的时候到达网格右下角的路径的数量,设f(i,j)是到达f[i][j]的路径数量,由于每次只能向下或者向右移动,所以可以用f(i,j)=f(i-1,j)+f(i,j-1)来计算路径数量,其中f(i-1,j)是指到f[i][j]上一格的数量,f(i,j-1)是指到达f[i][j]左边一格的路径数量,那么动态方程为f(i,j)=f(i-1,j)+f(i,j-1),最后返回f(m-1,n-1)的值即为所求,详细的视频讲解点击视频讲解-不同路径。
时间复杂度
由于要对整个二维数组进行遍历计算,所以时间复杂度为O(mn),需要开辟一个二维数组来存储对应格子的路径数,所以空间复杂度也为O(mn)
代码实现

class Solution {public int uniquePaths(int m, int n) {int[][] f = new int[m][n];for(int[] item : f){Arrays.fill(item,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];}
}

知识点扩展
对数组元素进行初始化设置可以使用以下函数,需要注意的是是的,Arrays.fill(nums,x)方法只能用于一维数组。该方法用指定的值填充整个数组,对于多维数组,每个维度需要分别使用fill方法进行填充。

//将nums数组的元素初始化为x
Arrays.fill(nums,x)

63.不同路径Ⅱ

思路
本题是62题的加强版,思路基本一样,都用到了动态规划的方法,唯一不同的是本题中多了一个障碍物的限制,有障碍物的网格是不能经过的,所以我们只要加一个判断条件,如果某个网格有障碍物,则将这个网格的可到达路径设置为0即可,需要注意的是本题不能将记录路径数的二维数组初始化值为1,而应该是0,62题中第一行(i=0)和第一列(j=0)因为只能向右和向下走才能到达,所以将其初始值设置为1,在后续的遍历中就可以直接从i=1j=1开始遍历数组,但是本题中第一行和第一列可能会出现障碍物,所以也要统一处理,遍历时也需要从0开始,同时为了保证第一行和第一列没有障碍物时可能正确的记录其可到达的路径数量,需要将其实位置的路径数置为1,视频讲解点击视频讲解-不同路径Ⅱ。
时间复杂度
时间复杂度和空间复杂度同62题,均为O(mn)
代码实现

class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;int[][] f = new int[m][n];for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){//判断是否有障碍物,有则直接跳过if(obstacleGrid[i][j] == 1) continue;//将f[0][0] = 1,方便对第一行和第一列的路径数的计算if(i == 0 && j == 0) f[i][j] = 1;else{//i>0时 路径数等于到达上面格子的路径数+f[i][j]if(i > 0) f[i][j] += f[i - 1][j];//j>0时 路径数等于到达左边格子的路径数+f[i][j]if(j > 0) f[i][j] += f[i][j - 1];}}}return f[m - 1][n - 1];}
}

64.最小路径和

思路
本题采用动态规划的方法来解决,设f(i,j)表示从(0,0)到(i,j)的路径和,由于每次只能向右或者向下走,所以可以得到以下的两个动态方程:

//从上面格子向下走
f[i][j] = f[i - 1][j] + grid[i][j]
//从左边格子向右走
f[i][j] = f[i][j - 1] + grid[i][j]

要得到最小路径和,所以两种走法中取最小值即可,所以最终的动态方程为:

f[i][j] = Math.min(f[i - 1][j],f[i][j - 1]) + grid[i][j]

注意最后在代码中不要直接使用该动态方程,因为要分别处理ij为0的情况,视频讲解点击视频讲解-最小路径和。
时间复杂度
由于要遍历二维数组得到每一格的路径和,所以时间复杂度为O(mn),开辟一个二维数组来记录每一格的路径和,所以空间复杂度为O(mn)
代码实现

class Solution {public int minPathSum(int[][] grid) {int m = grid.length;int n = grid[0].length;int[][] f = new int[m][n];//初始化为最大值for(int[] item : f){Arrays.fill(item,Integer.MAX_VALUE);}for(int i = 0;i < m;i++){for(int j = 0;j < n;j++){//(0,0)处的值为网格的值,特判处理if(i == 0 && j == 0) f[i][j] = grid[i][j];else{//处理j为0,即第一列的情况if(i > 0) f[i][j] = Math.min(f[i][j],f[i - 1][j] + grid[i][j]);//处理i为0,即第一行的情况if(j > 0) f[i][j] = Math.min(f[i][j],f[i][j - 1] + grid[i][j]);}}}return f[m - 1][n - 1];}
}

66.加一

思路
本题需要对数组元素组成的数字进行加一操作,重点在于加法操作中对进位的处理,可以分为两种情形:

  • 当数组最后一个元素小于9时,最后一个元素直接加一,然后直接返回数组即可。
  • 当数组最后一个元素大于9时,需要考虑到进位,将数组最后一个元素置为0,进位+1,然后继续对倒数第二个元素进行加一处理,依次类推。这里需要对数组元素全是9做特判处理,需要在结果数组的开头插入元素1。

视频讲解点击视频讲解-加一。
时间复杂度
这个算法的时间复杂度为O(n),其中n是输入数组digits的长度。在大多数情况下,算法只需遍历一次数组,因此时间复杂度为O(n)。但在最坏情况下,需要创建一个新的数组,并将所有元素复制到新数组中,此时时间复杂度为O(n+1),即O(n)。因此,可以将算法的时间复杂度简化为O(n)
代码实现

class Solution {public int[] plusOne(int[] digits) {for(int i = digits.length - 1 ;i >= 0; i--){if(digits[i] < 9){digits[i]++;break;}else{digits[i] = 0;if(i == 0){int[] newdigits = new int[digits.length + 1];newdigits[0] = 1;for(int j = 1; j < digits.length + 1 ;j++){newdigits[j] = digits[j - 1];}digits = newdigits;}}}return digits;}
}

67.二进制求和

思路
本题直接对二进制进行求和,使用StringBuilder来构建结果字符串(关于StringBuilder的使用下面的知识拓展中做了总结,之前系列文章中也有简单介绍(LeetCode-hot100题解—Day3中 17.电话号码的字母组合),因为要动态的往结果数组里添加元素,所以不建议直接使用String),并使用carry变量来记录进位。从字符串的末尾开始,逐位相加,并将结果插入到StringBuilder的开头。代码中将ab两个字符串中对应位置的元素全部加到carry中,最后使用carry%2得到结果,carry/2更新carry的值。视频讲解点击视频讲解-二进制求和,其中有详细的模拟演示。
时间复杂度
该方法的时间复杂度为O(max(n,m)),其中分别是字符串ab的长度。在最坏情况下,需要遍历较长的字符串并执行常数时间操作。所以时间复杂度可以看成O(n)
代码实现

class Solution {public String addBinary(String a, String b) {StringBuilder ans = new StringBuilder();int carry = 0;int i = a.length() - 1;int j = b.length() - 1;while(i >= 0 || j >= 0 || carry > 0){if(i >= 0){carry += a.charAt(i) - '0';i--;} if(j >= 0){carry += b.charAt(j) - '0';j--;}        ans.insert(0,carry % 2);carry /= 2;}return ans.toString();}
}

知识拓展
以下总结了StringBuilder的一些基本用法,需要注意的是,StringBuilder是线程不安全的,如果需要在多线程环境中使用,应该考虑使用StringBuffer类。

//1.创建StringBuilder对象
//创建一个空的StringBuilder对象
StringBuilder s = new StringBuilder();
//创建一个包含初始字符串的StringBuilder对象
StringBuilder s = new StringBuilder("Hello");
//创建一个初始容量为100的StringBuilder对象
StringBuilder s = new StringBuilder(100);//2.添加字符串或字符
//添加字符串
s.append("World")
//添加空字符串
s.append(" ");
//添加一个字符
s.append('!');//3.插入字符串或字符
//在索引5处插入字符串"world"
s.insert(5,"world");
//在索引0处插入字符'!'
s.insert(0,'!');//4.删除字符或字符串
//删除索引5到10之间的字符,包括索引为5的字符,不包括索引为10的字符,左闭右开
s.delete(5,10);
//删除索引0处的字符
s.deleteCharAt(0);//5.替换字符串或字符
//替换索引5到10之间的字符为"nihao"
s.replace(5,10,"nihao");
//替换索引0处的字符为"N"
s.replace(0,1,"N");//6.获取字符串
//将StringBuilder对象转换为字符串
String str = s.toString();

69.x的平方根

思考
由于题目不允许使用任何内置指数函数和算符,所以采用二分查找来解决该问题。首先定义左右边界,计算中点mid的平方值,如果该值小于等于x值,则说明x的平方根在mid的右侧,此时更新左边界l的值为mid(因为mid的值也可能是结果);如果该值大于x,则说明x的平方根在mid的左侧,此时更是右边界r的值为mid-1mid的平方值大于x,所以mid肯定不是所求的结果),最后循环结束,返回l和r任意一个即为所求,视频讲解点击视频讲解-x的平方根。
时间复杂度
使用二分查找,时间复杂度为O(logn)
代码实现

class Solution {public int mySqrt(int x) {int l = 0;int r = x;while(l < r){int mid = l + (r - l) / 2 + 1;if((long)mid * mid <= x) l = mid;else r = mid - 1; }return l;}
}

70.爬楼梯

思路:
本题采用动态规划来解决,假设f(i)表示爬到i阶的方法数,那么f(1) = 1,第1阶爬1阶到达,有一种方法,f(2)=2,第2阶可以可以从1阶爬到2阶,也可以直接爬2阶到2,所以有两种方法;由于一次可以爬1阶或2阶,所以动态方程为f(i)=f(i-1)+f(i-2),其中f(i-1)表示爬到i-1阶的方法数,爬到i需要爬1阶,可以到达i阶,f(i-2)表示爬到i-2阶的方法数,爬到i阶需要爬2阶,可以到达i阶,两者加起来即为爬到i阶的方法数,视频讲解点击视频讲解-爬楼梯。
时间复杂度
时间复杂度为O(n),由于开辟了一个数组来保存爬到每一阶的方法数,空间复杂度为O(n)
代码实现

class Solution {public int climbStairs(int n) {//数组大小设置为n+2,防止溢出int[] f = new int[n + 2];f[1] = 1;f[2] = 2;for(int i = 3;i <= n;i++){f[i] = f[i - 1] + f[i - 2];}return f[n];}
}

71.简化路径

思路
根据题意可知,当在路径中遇到"."时表明当前目录,不做处理;当在路径中遇到".."时表明上级目录,需要返回上级目录,所以可以将path中的目录全部压入栈中,当遇到".."时,弹出栈顶元素(即回到上一级目录),最后在遍历完path后将栈中的元素逆序拼接输出即可,如果栈为空,直接返回根目录"/",视频讲解点击视频讲解-简化路径。关于javaStack的使用在之前系列文章(LeetCode-hot100题解—Day3 20.有效的括号)中总结过,如果需要可以去复习一下。
时间复杂度
时间复杂度是O(n),其中n是路径字符串path的长度,只对path进行了一次遍历。
代码实现

class Solution {public String simplifyPath(String path) {Stack<String> stk = new Stack<>();String[] items = path.split("/");for(String item : items){if(item.equals("..")){if(!stk.isEmpty()){stk.pop();}}else if(!item.equals(".") && !item.equals("")){stk.push(item);}}StringBuilder ans = new StringBuilder();while(!stk.isEmpty()){ans.insert(0,"/"+stk.pop());}//如果栈为空,直接返回根目录"/"return ans.length() == 0 ? "/" : ans.toString();}
}

知识拓展
equals==的使用
使用"=="运算符判断两个对象是否相等时,它实际上比较的是两个对象的引用地址,而不是它们的值,也就是说,它检查的是两个对象是否指向相同的内存位置。
而使用equals()方法可以比较两个对象的值是否相等,equals() 不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。在Java中,equals()方法是Object类的方法,所有的类都继承了它。默认情况下,equals()方法与"=="运算符的行为相同,比较的是两个对象的引用地址。
但是,很多类会覆盖equals()方法,以便根据对象的内容来判断它们是否相等。例如,在字符串类(String)中,String 中的 equals 方法是被重写过的,equals()方法比较的是字符串的内容(也就是对象的值),而不是引用地址。
因此,如果你想比较两个对象的值是否相等,应该使用equals()方法,而不是"=="运算符。

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

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

相关文章

UE5自动生成地形一:地形制作

UE5自动生成地形一&#xff1a;地形制作 常规地形制作地形编辑器地形管理添加植被手动修改部分地形的植被 置换贴图全局一致纹理制作地貌裸露岩石地形实例 常规地形制作 地形制作入门 地形导入部分 选择模式&#xff1a;地形模式。选择地形子菜单&#xff1a;管理->导入 …

STC8增强型单片机开发——C51版本Keil环境搭建

一、目标 了解C51版本Keil开发环境的概念和用途掌握C51版本Keil环境的安装和配置方法熟悉C51版本Keil开发环境的使用 二、准备工作 Windows 操作系统Keil C51 安装包&#xff08;可以从Keil官网下载&#xff09;一款8051单片机开发板 三、搭建流程 环境搭建的基本流程&#xf…

思维导图网页版哪个好?2024年值得推荐的8个在线思维导图软件!

思维导图如今已成为一种常用的工具&#xff0c;帮助我们清晰地组织和整理信息。随着科技的发展&#xff0c;思维导图的产品形态也经过多轮迭代&#xff0c;从最初的本地客户端过渡到基于云的 Web 端&#xff0c;各类网页版思维导图软件应运而生&#xff0c;它们方便快捷&#x…

【Linux】gcc/g++的使用

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; Linux &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好&#xff0c;本片文章将会讲解Linux中gcc/g使用的相关内容。 如果看到最后您觉得这篇文章写得不错…

【Linux】CAN根据时钟频率、波特率计算采样点详解

1、采样点知识回顾 参考博客:【CAN】知识点:帧类型、数据帧结构、传输速率、位时间、采样点 CAN 采样点是指在一个数据位的传输周期内,接收器实际采样数据的时间点。这个时间点是以百分比来表示的,它决定了在数据位的传输周期中,何时读取数据位的值。 正确设置采样点对…

js api part3

环境对象 环境对象&#xff1a; 指的是函数内部特殊的 变量 this &#xff0c; 它代表着当前函数运行时所处的环境 作用&#xff1a; 弄清楚this的指向&#xff0c;可以让我们代码更简洁 函数的调用方式不同&#xff0c;this 指代的对象也不同 【谁调用&#xff0c; this 就是…

Qt | QLineEdit 类(行编辑器)

01、上节回顾 Qt | QComboBox(组合框)02、QLineEdit 1、QLineEdit 类是 QWidget 类的直接子类,该类实现了一个单行的 输入部件,即行编辑器,见右图 2、验证器(QValidator 类)和输入掩码简介:主要作用是验证用户输入的字符是否符合验证器 的要求,即限制对用户的输入,比…

【C#_变量_格式化输出_If语句_微信猜拳_第一篇】

C#&#xff08;编程入门&#xff09; 练习来自腾讯课堂免费课程1.1.基本输出语句基本输出语句——知识点总结Console.Clear();清屏字符串和数字区分Console.ReadLine(); 1.2.变量的基本使用&#xff1a;变量的基本使用——知识点总结 1.3.格式化输出格式化输出——知识点总结 1…

01 设计模式--单例模式

1. 单例模式 单例模式有两种实现方式&#xff1a; 1.1 饿汉模式&#xff08;Eager Initialization&#xff09;&#xff1a;在类加载时就创建单例实例&#xff0c;无论是否需要使用该实例。 饿汉模式在类加载时就创建单例实例&#xff0c;无论是否需要使用该实例。 饿汉模式…

C++ Primer 中文版(第 5 版)-第二单元

第二单元 练习 2.1 通过读下面程序&#xff0c;写出程序运行结果。 #include <iostream>int main() {unsigned u 10, u2 42;std::cout << u2 - u << std::endl;std::cout << u - u2 << std::endl;int i 10, i2 42;std::cout << i2 …

论文阅读_使用有向无环图实现流程工程_AgentKit

英文名称: AgentKit: Flow Engineering with Graphs, not Coding 中文名称: AgentKit&#xff1a;使用图而非编码进行流程工程 链接: https://arxiv.org/pdf/2404.11483.pdf 代码: https://github.com/holmeswww/AgentKit 作者: Yue Wu, Yewen Fan, So Yeon Min, Shrimai Prabh…

Julia 语言环境安装与使用

1、Julia 语言环境安装 安装教程&#xff1a;https://www.runoob.com/julia/julia-environment.html Julia 安装包下载地址为&#xff1a;https://julialang.org/downloads/。 安装步骤&#xff1a;注意&#xff08;勾选 Add Julia To PATH 自动将 Julia 添加到环境变量&…

ollama + autogen排雷

语法&#xff1a;<abc>代表参数&#xff0c;实际输入为具体的名字&#xff0c;不需要输入<> 注意&#xff1a;当前雷可能随着版本迭代更新掉 1、litellm -model ollama/<model> 启动后的url为&#xff1a;http://0.0.0.0:<port>&#xff0c;实际调用…

实用 Linux 操作指令

实用 Linux 操作指令 Linux 命令行提供了强大的功能&#xff0c;可以通过一系列指令轻松管理系统、文件和网络。以下是一些常用的 Linux 操作指令&#xff0c;涵盖文件管理、系统监控、网络配置等方面。 一、文件管理 显示当前目录&#xff1a; pwd列出目录内容&#xff1a; …

薪酬激励策略:留住企业核心人才的关键

在竞争激烈的商业环境中&#xff0c;企业为了保持竞争力和市场地位&#xff0c;必须高度重视人才的管理和发展。企业的核心人才是推动企业发展的关键因素&#xff0c;因此&#xff0c;如何有效地激励和留住这些核心人才&#xff0c;成为企业持续发展的关键之一。薪酬激励策略作…

C语言 函数的嵌套与递归 调用

本文 我们来说函数的嵌套调用和递归调用 在很多大型项目中 我们肯定不可能将所有逻辑都写在一个函数中 肯定要按功能拆解成多个特定的功能函数 函数并不允许嵌套调用&#xff0c;但是 允许在逻辑代码中嵌套调用 所谓函数嵌套调用 就是在一个函数中调用另一个函数&#xff0c;而…

【计算机毕业设计】基于SSM++jsp的菜匣子优选系统【源码+lw+部署文档+讲解】

目录 第一章 绪 论 第二章 关键技术的研究 2.1 JSP技术介绍 2.2 JAVA简介 2.3 ECLIPSE 开发环境 2.4 Tomcat服务器 2.5 MySQL数据库 第三章 系统分析 3.1 系统设计目标 3.2 系统可行性分析 3.3 系统功能分析和描述 3.4系统UML用例分析 3.4.1管理员用例 3.4.2用户用例 3.5系统流…

C语言 计数控制循环

今天 我们来说 计数控制的循环 对于循环次数 我们已知的循环 我们称之为 计数控制的循环 这种情况 我们一般选择 for来实现 更为方便 先看一个案例 求 1 到 N 的累加合 我们代码可以这样写 #define _CRT_SECURE_NO_WARNINGS//禁用安全函数警告 #pragma warning(disable:6031…

python中flask使用简要记录

文档层级概要 一、flask简要说明 二、uwsgi配置说明 三、启动 四、结果验证 之前有做过接口&#xff0c;后来写了许多算法和数据处理&#xff0c;对于接口大多时候是通过fastapi或调别人的接口。自己写的接口倒是没有多少。在这里使用uwsgi和flask及nginx进行配置&#xf…

[链表专题]力扣LCR077, 83

1. LCR077 : 排序链表 题 : 给定链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。示例 1&#xff1a;输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a;输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,…