怒刷LeetCode的第3天(Java版)
目录
第一题
题目来源
题目内容
解决方法
方法一:动态规划
第二题
题目来源
题目内容
解决方法
方法一:模拟
方法二:数学规律
方法三:分组
第三题
题目来源
题目内容
解决方法
方法一:数学方法
方法二:转换字符串
第一题
题目来源
213. 打家劫舍 II - 力扣(LeetCode)
题目内容

解决方法
方法一:动态规划
这道题可以使用动态规划的方法求解。首先,我们观察到第一个房屋和最后一个房屋是相邻的,因此它们不能同时被偷窃。所以,我们可以将问题分成两种情况来考虑:
-
偷窃第一个房屋但不偷窃最后一个房屋:在这种情况下,我们只需要计算从第一个房屋到倒数第二个房屋能够偷窃到的最高金额。
-
不偷窃第一个房屋但偷窃最后一个房屋:在这种情况下,我们只需要计算从第二个房屋到最后一个房屋能够偷窃到的最高金额。
对于每一种情况,我们可以使用动态规划来求解。定义一个长度为n的数组dp,其中dp[i]表示从第一个房屋到第i个房屋能够偷窃到的最高金额。那么,我们有以下状态转移方程:
-
对于第一种情况,dp[i] = max(dp[i-2] + nums[i], dp[i-1]),其中dp[i-2] + nums[i]表示偷窃第i个房屋得到的金额,dp[i-1]表示不偷窃第i个房屋得到的金额。
-
对于第二种情况,dp[i] = max(dp[i-1], dp[i-2] + nums[i]),其中dp[i-1]表示不偷窃第i个房屋得到的金额,dp[i-2] + nums[i]表示偷窃第i个房屋得到的金额。
最后,我们可以将第一种情况和第二种情况的结果取较大值作为最终的结果,即max(dp[n-2], dp[n-1]),其中n是数组nums的长度。
class Solution {public int rob(int[] nums) {int n = nums.length;if (n == 1) {return nums[0];}return Math.max(robHouse(nums, 0, n - 2), robHouse(nums, 1, n - 1));}private int robHouse(int[] nums, int start, int end) {int pre2 = 0, pre1 = 0;for (int i = start; i <= end; i++) {int cur = Math.max(pre2 + nums[i], pre1);pre2 = pre1;pre1 = cur;}return pre1;}
}
在上述解法中,我们使用了动态规划的思想来解决问题。接下来我们来分析一下该解法的时间复杂度和空间复杂度。
时间复杂度分析:
- 在计算偷窃第一种情况的最高金额时,我们需要遍历从第一个房屋到倒数第二个房屋,因此时间复杂度为O(n)。
- 在计算偷窃第二种情况的最高金额时,我们需要遍历从第二个房屋到最后一个房屋,同样时间复杂度为O(n)。
- 最后取两种情况的较大值作为最终结果,时间复杂度为O(1)。 综上所述,该解法的时间复杂度为O(n)。
空间复杂度分析:
- 我们使用了一个长度为n的dp数组来保存每个房屋能够偷窃到的最高金额,因此空间复杂度为O(n)。
- 另外,我们还使用了常量级的额外空间来保存前两个房屋的偷窃金额,所以空间复杂度为O(1)。 综上所述,该解法的空间复杂度为O(n)。
总结: 该解法的时间复杂度为O(n),空间复杂度为O(n)。在给定限制条件下,这是一个较优的解法。
LeetCode运行结果:

第二题
题目来源
6. N 字形变换 - 力扣(LeetCode)
题目内容


解决方法
方法一:模拟
这个问题可以使用模拟的方法来解决。我们可以创建一个长度为numRows的字符串数组,表示Z字形排列后每一行的字符串。然后遍历原始字符串s,将每个字符按照Z字形的规律放入对应的行中。
具体步骤如下:
- 若numRows为1或s的长度小于等于numRows,则直接返回s作为结果。
- 创建一个长度为numRows的字符串数组rows,用于保存每一行的字符串。
- 创建一个变量rowIndex,初始值为0,表示当前所在的行。
- 创建一个变量goingDown,初始值为true,表示当前的方向是向下。
- 遍历字符串s的每个字符:
- 将当前字符加入rows[rowIndex]中。
- 如果当前的方向是向下且当前行不是最后一行,则向下移动到下一行(rowIndex++)。
- 如果当前的方向是向上且当前行不是第一行,则向上移动到上一行(rowIndex--)。
- 如果当前行是第一行或最后一行,则改变方向(goingDown = !goingDown)。
- 将数组rows中的每个字符串按顺序连接起来,即为结果。
class Solution {public String convert(String s, int numRows) {if (numRows == 1 || s.length() <= numRows) {return s;}String[] rows = new String[numRows];for (int i = 0; i < numRows; i++) {rows[i] = "";}int rowIndex = 0;boolean goingDown = true;for (char c : s.toCharArray()) {rows[rowIndex] += c;if (goingDown && rowIndex < numRows - 1) {rowIndex++;} else if (!goingDown && rowIndex > 0) {rowIndex--;}if (rowIndex == 0 || rowIndex == numRows - 1) {goingDown = !goingDown;}}StringBuilder result = new StringBuilder();for (String row : rows) {result.append(row);}return result.toString();}
}
复杂度分析如下:
时间复杂度:
- String转换为char数组的时间复杂度是O(n),其中n为字符串s的长度。
- 遍历字符数组并按规则放入对应行的时间复杂度是O(n)。
- 将数组中的每个字符串连接起来的时间复杂度是O(numRows)。
- 因此,总体时间复杂度为O(n)。
空间复杂度:
- 创建了一个长度为numRows的字符串数组rows,所以额外的空间复杂度是O(numRows)。
- 除此之外,没有使用其他额外的空间。
- 因此,总体空间复杂度也是O(numRows)。
综上所述,该解法的时间复杂度和空间复杂度都是O(n),其中n为字符串s的长度。
LeetCode运行结果:

方法二:数学规律
除了模拟方法外,还可以使用数学规律来解决这个问题。
观察Z字形变换的规律,可以发现以下几个关键点:
- 第一行和最后一行中的字符之间的距离为周期性的,即间隔为2 * numRows - 2。
- 中间行的字符之间的距离有两个部分组成,一个是上方的字符与下方的字符之间的距离,为周期性的,间隔同样为2 * numRows - 2。另一个是斜对角方向的字符与当前字符之间的距离,为固定值,为2 * numRows - 2 - 2 * i,其中i为当前行的索引。
- 对于原始字符串中每个字符的位置,可以通过行索引和列索引来确定。
基于以上观察,可以直接计算每个字符在变换后字符串中的位置,然后将其按顺序放入结果字符串中。
class Solution {public String convert(String s, int numRows) {if (numRows == 1 || s.length() <= numRows) {return s;}StringBuilder result = new StringBuilder();int cycleLen = 2 * numRows - 2;int n = s.length();for (int i = 0; i < numRows; i++) {for (int j = 0; j + i < n; j += cycleLen) {result.append(s.charAt(j + i));if (i != 0 && i != numRows - 1 && j + cycleLen - i < n) {result.append(s.charAt(j + cycleLen - i));}}}return result.toString();}
}
复杂度分析如下:
时间复杂度:
- 遍历每个字符并确定其位置的时间复杂度是O(n),其中n为字符串s的长度。
- 在遍历过程中,对于每个字符,最多进行两次append操作。
- 因此,总体时间复杂度仍然为O(n)。
空间复杂度:
- 只使用了常数级别的额外空间,即StringBuilder中的空间。
- 因此,空间复杂度是O(1)。
综上所述,使用数学规律的方法的时间复杂度和空间复杂度分别为O(n)和O(1),其中n为字符串s的长度。相比于模拟方法,这种方法在空间复杂度上有优势,因为不需要额外的数组来存储每一行的字符串。
LeetCode运行结果:

方法三:分组
除了前面介绍的方法,还可以使用分组方法来完成Z字形变换。
具体步骤如下:
- 创建一个长度为numRows的字符串数组rows,用来存储每一行的字符。
- 遍历原始字符串s,按照特定的分组规则将每个字符放入对应的分组中。
- 第一组的长度为2 * numRows - 2。
- 后续的每一组的长度也是2 * numRows - 2,但是每个字符在分组中的位置会有所不同。
- 对于中间的行(行索引1到numRows-2),每个分组包含两个字符,分别位于当前行和其对称行中。
- 对于首尾两行(行索引0和numRows-1),每个分组只包含一个字符,位于对应行中。
- 遍历完成后,将每一行的字符串按顺序拼接成最终的结果字符串。
class Solution {public String convert(String s, int numRows) {if (numRows == 1 || s.length() <= numRows) {return s;}String[] rows = new String[numRows];Arrays.fill(rows, "");int groupSize = 2 * numRows - 2;for (int i = 0; i < s.length(); i++) {int remain = i % groupSize;int row = remain < numRows ? remain : groupSize - remain;rows[row] += s.charAt(i);}StringBuilder result = new StringBuilder();for (String row : rows) {result.append(row);}return result.toString();}}
复杂度分析如下:
-
时间复杂度:
- 遍历整个字符串s的时间复杂度为O(n)。
- 将每个字符放入对应分组的时间复杂度为O(1)。
- 因此,总的时间复杂度为O(n)。
-
空间复杂度:
- 创建了一个大小为numRows的字符串数组rows,因此空间复杂度为O(numRows) = O(n)。这里假设numRows远小于n,可以忽略。
LeetCode运行结果:

第三题
题目来源
7. 整数反转 - 力扣(LeetCode)
题目内容

解决方法
方法一:数学方法
要反转一个整数,可以使用数学方法。
具体步骤如下:
需要注意的是,该代码假设输入的整数为32位有符号整数。如果输入的整数超过了范围,或者溢出反转后的整数范围,将返回0。
- 初始化一个变量
res用于存储反转后的整数。 - 进入循环,当原始整数不为0时,执行以下操作:
- 通过取余运算获取原始整数的最后一位数字,保存在
digit中。 - 检查反转后的整数是否有可能溢出,如果溢出则返回0。具体的判断条件如下:
- 如果
res大于Integer.MAX_VALUE / 10,或者当res等于Integer.MAX_VALUE / 10且digit大于7,则表示溢出,返回0。 - 如果
res小于Integer.MIN_VALUE / 10,或者当res等于Integer.MIN_VALUE / 10且digit小于-8,则表示溢出,返回0。
- 如果
- 更新
res的值,将res乘以10并加上digit。 - 将原始整数除以10,以便获取下一位数字。
- 通过取余运算获取原始整数的最后一位数字,保存在
- 循环结束后,返回
res,即为反转后的整数。
class Solution {public int reverse(int x) {int res = 0;while (x != 0) {int digit = x % 10;if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && digit > 7)) {return 0;}if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && digit < -8)) {return 0;}res = res * 10 + digit;x /= 10;}return res;}
}
复杂度分析如下:
- 这段代码的时间复杂度是 O(log|x|),其中 x 是输入的整数。在循环中,每次都会将原始整数除以10,因此循环的次数与输入的整数的位数相关。由于一个整数的位数大约为 log|x|(以10为底),所以循环的次数也大约为 log|x|。另外,在循环内部执行的操作包括取余运算、比较和乘法操作,这些操作的时间复杂度都可以忽略不计。因此,整体的时间复杂度可以近似地看作 O(log|x|)。
- 空间复杂度为 O(1),因为只使用了常数个变量来存储结果和临时值,没有使用额外的数据结构。
LeetCode运行结果:

方法二:转换字符串
要实现整数反转的功能,可以按照以下步骤进行:
- 将输入的整数转换为字符串。
- 判断整数是否为负数,如果是负数,则将符号标记下来,并将整数转换为正数处理。
- 将字符串逆序排列。
- 将逆序后的字符串转换回整数。
- 如果原整数为负数,则将结果乘以-1。
class Solution {public int reverse(int x) {// 转换为字符串String str = Integer.toString(x);// 判断是否为负数boolean isNegative = false;if (str.charAt(0) == '-') {isNegative = true;str = str.substring(1); // 移除负号}// 逆序排列字符串StringBuilder sb = new StringBuilder(str);sb.reverse();String reversedStr = sb.toString();// 转换回整数long result = Long.parseLong(reversedStr);// 处理溢出情况if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {return 0;}// 处理负数if (isNegative) {result *= -1;}return (int)result;}
}
复杂度分析:
时间复杂度分析:
- 转换为字符串:这个步骤的时间复杂度是O(log|x|),其中|x|是输入整数的绝对值。
- 判断是否为负数:这个步骤的时间复杂度是O(1)。
- 逆序排列字符串:使用StringBuilder的reverse方法,时间复杂度为O(log|x|)。
- 将逆序后的字符串转换为长整型:使用Long.parseLong方法,时间复杂度同样为O(log|x|)。
- 处理溢出情况、处理负数:这两个步骤的时间复杂度都是O(1)。
- 返回结果:同样也是O(1)的时间复杂度。
综上所述,整体的时间复杂度可以视为O(log|x|)。
空间复杂度分析:
- 字符串转换和逆序排列过程中会使用StringBuilder对象来构建字符串,所以它的空间复杂度为O(log|x|)。
- 其他变量的空间复杂度是常数级的,不随输入规模变化。
因此,整体的空间复杂度可以视为O(log|x|)。
需要注意的是,这里的|x|是指输入整数的绝对值的位数。由于整数的位数在实际问题中通常是固定的,因此我们可以将该算法的时间复杂度和空间复杂度视为O(1)。
LeetCode运行结果:

相关文章:
怒刷LeetCode的第3天(Java版)
目录 第一题 题目来源 题目内容 解决方法 方法一:动态规划 第二题 题目来源 题目内容 解决方法 方法一:模拟 方法二:数学规律 方法三:分组 第三题 题目来源 题目内容 解决方法 方法一:数学方法 方法…...
JavaScript数组去重常用方法
数组去重是在 JavaScript 开发中经常遇到的问题。本文将从前言、分析、使用场景、具体实现代码和注意事项等方面,详细讨论 JavaScript 数组去重的方法。 前言: 在 JavaScript 中,数组是一种常用的数据结构,用于存储多个值。然而…...
蓝牙电话之HFP—电话音频
1 媒体音频: 播放蓝牙音乐的数据,这种音频对质量要求高,数据发送有重传机制,从而以l2cap的数据形式走ACL链路。编码方式有:SBC、AAC、APTX、APTX_HD、LDAC这五种编码方式,最基础的编码方式是SBC࿰…...
JDBC基本概念
什么是JDBC JDBC概念 JDBC(Java DataBase Connectivity)是一套统一的基于Java语言的关系数据库编程接口规范。 该规范允许将SQL语句作为参数通过JDBC接口发送给远端数据库, …...
leetcode876 链表的中间节点
题目 给你单链表的头结点 head ,请你找出并返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 示例 输入:head [1,2,3,4,5] 输出:[3,4,5] 解释:链表只有一个中间结点,值为 3 。 输入&a…...
了解方法重写
父类 package com.mypackage.oop.demo07;//重写都是方法的重写,与属性无关 public class B {public static void test(){System.out.println("B>test.()");}public void test2(){System.out.println("B2>test.()");} }子类 package com…...
2、从“键鼠套装”到“全键盘游戏化”审核
1、风行内容仓的增效之路 - 前言 内容仓成立初期,安全审核组是规模最大的小组,占到部门人数的半壁江山,因此增效工作首先就从安全审核开始。 早期安全审核每天的达标值在800条左右,每天的总审核量不到1万,距离业务部门…...
【flutter】架构之商城main入口
架构之商城main入口 前言一、项目模块的划分二、入口main的配置三、配置文件怎么做总结 前言 本栏目我们将完成一个商城项目的架构搭建,并完善中间的所有功能,总页面大概200个,如果你能看完整个栏目,你肯定能独立完成flutter 项目…...
linux学习实操计划0103-安装软件
本系列内容全部给基于Ubuntu操作系统。 系统版本:#32~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 18 10:40:13 UTC 1 安装deb格式软件 Debian包是Unixar的标准归档,将包文件信息以及包内容,经过gzip和tar打包而成。 处理这些包的经典程序是…...
git vscode
01:工作区 **02:暂存区 git add . 3:本地库 git commit -m ’ 4:远程库 git push example 点击箭头之后...
Linux命令行批量删除文件
1、 删除当前目录下60min前的所有.log结尾文件 find ./ -type f -name "*.log" -mmin 60 -delete 2、删除当前目录下30天前的所有.log结尾文件 find ./ -type f -name "*.log" -mtime 30 -delete...
CAN - 基础
CAN 基础 概念分类特点物理层收发器线与编码方式通信方式采样点/位 常见故障 数据链路层CAN控制器数据帧分类数据帧格式数据帧DBC解析CRC校验远程帧 总线竞争与仲裁非破坏性仲裁机制 节点状态与错误处理机制节点状态错误处理机制错误帧 概念 分类 CANCAN FD高速CAN低俗容错CA…...
【Hash表】找出出现一次的数字-力扣 136
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...
Resize和centerCrop的区别
首先要记住,transforms只能对PIL读入的图片进行操作,而且PIL和opencv只能读取H * W * C形式的图片。 resize(size):将图片的短边缩放成size的比例,然后长边也跟着缩放,使得缩放后的图片相对于原图的长宽比不变。如果想要resize成自己想要的图…...
无涯教程-JavaScript - SUM函数
描述 SUM函数可添加值。 语法 SUM (number1, [number2]...)争论 Argument描述Required/Optionalnumber1The first number you want to add. The number can be a value, a cell reference, or a cell range.Requirednumber2, …You can specify up to 255 additional numbe…...
ChatGLM P-Tuningv2微调定制AI大模型
前言 什么是模型微调 想象一下,你正在学习如何弹奏一首钢琴曲目。你已经学会了一些基本的钢琴技巧,但你想要更进一步,尝试演奏一首特定的曲目。这时,你会选择一首你感兴趣的曲目,并开始深度练习。 Fine-tuning(微调)在机器学习中也是类似的概念。当我们使用预先训练好…...
关于RISC-V安全性的全面综述
目录 摘要引言RISC-V安全综述通用平台的安全要求信任的根源与硬件安全模块OTP管理模块安全内存对称加密(如AES)引擎不对称加密[131](例如,公钥RSA)引擎HASH/HAMC引擎随机数/位生成(例如TRNG[136]࿰…...
Python基础语法规则和Java不同的地方
Java是现在最流行的语言,也是广大程序员最熟悉的语言。然而,随着人工智能领域的快速发展,Python作为新星崭露头角。通过对比Java语言来学习Python语言,可以事半功倍。 首先,我们来看Python和Java在注释上的区别。在Jav…...
振弦采集仪安全监测路基边坡的解决方案
振弦采集仪安全监测路基边坡的解决方案 随着人们对交通安全的重视和公路工程的发展,路基边坡安全监测成为了重要的课题之一。路基边坡作为公路的基础,其稳定性直接关系到公路的使用寿命和行车安全。而振弦采集仪作为一种新型的安全监测设备,可…...
如何与QVC 建立EDI连接?
QVC,全称为Quality, Value, Convenience(品质、价值、便利),成立于1986年,是一家全球领先的零售电视和在线零售商。作为一家多渠道零售商,QVC致力于为客户提供高品质、独特的商品,通过电视、互联…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
