怒刷LeetCode的第6天(Java版)
目录
第一题
题目来源
题目内容
解决方法
方法一:哈希表
方法二:逐个判断字符
方法三:模拟减法
第二题
题目来源
题目内容
解决方法
方法一:水平扫描法
方法二:垂直扫描法
方法三:分治法
方法四:二分查找
第三题
题目来源
题目内容
解决方法
方法一:双指针
第一题
题目来源
13. 罗马数字转整数 - 力扣(LeetCode)
题目内容


解决方法
方法一:哈希表
根据题目要求,我们需要将给定的罗马数字转换成整数。根据题目中给出的规则,我们可以逐个字符判断并累加得到最终的整数表示。
具体的步骤如下:
- 初始化一个变量result为0,表示最终的整数结果。
- 遍历给定的罗马数字字符串s,从左往右逐个字符判断:
- 如果当前字符的值比下一个字符的值小,则需要执行减法操作。根据题目中的特殊规则,可以判断当前字符的值是负数。将该负数加到result上,并跳过下一个字符。
- 否则,直接将当前字符的值加到result上。
- 返回result作为最终的整数表示。
class Solution {public int romanToInt(String s) {Map<Character, Integer> romanMap = new HashMap<>();romanMap.put('I', 1);romanMap.put('V', 5);romanMap.put('X', 10);romanMap.put('L', 50);romanMap.put('C', 100);romanMap.put('D', 500);romanMap.put('M', 1000);int result = 0;for (int i = 0; i < s.length(); i++) {int value = romanMap.get(s.charAt(i));if (i < s.length() - 1 && value < romanMap.get(s.charAt(i + 1))) {result -= value;} else {result += value;}}return result;
}}
复杂度分析:
- 时间复杂度:O(n),其中n是给定的罗马数字字符串的长度。遍历一次罗马数字字符串,每个字符只被访问一次。
- 空间复杂度:O(1)。虽然我们使用了一个哈希表来存储罗马数字字符与对应的数值映射关系,但是由于罗马数字字符数量有限且固定,因此哈希表的大小是恒定不变的,可以视为常数级别的空间复杂度。除此之外,我们并没有使用任何额外的数据结构。
LeetCode运行结果:

方法二:逐个判断字符
除了使用哈希表的方法,还可以使用逐个判断字符的方法来将罗马数字转换成整数。
具体的步骤如下:
-
初始化一个变量
result为0,表示最终的整数结果。 -
遍历给定的罗马数字字符串
s,从左往右逐个字符判断:-
如果当前字符是'I',并且下一个字符是'V'或'X',则需要执行减法操作,将4或9加到
result上,并跳过下一个字符。 -
如果当前字符是'X',并且下一个字符是'L'或'C',则需要执行减法操作,将40或90加到
result上,并跳过下一个字符。 -
如果当前字符是'C',并且下一个字符是'D'或'M',则需要执行减法操作,将400或900加到
result上,并跳过下一个字符。 -
否则,直接将当前字符的值加到
result上。
-
-
返回
result作为最终的整数表示。
class Solution {public int romanToInt(String s) {int result = 0;for (int i = 0; i < s.length(); i++) {char currentChar = s.charAt(i);if (currentChar == 'I' && i < s.length() - 1 && (s.charAt(i + 1) == 'V' || s.charAt(i + 1) == 'X')) {result -= 1;} else if (currentChar == 'X' && i < s.length() - 1 && (s.charAt(i + 1) == 'L' || s.charAt(i + 1) == 'C')) {result -= 10;} else if (currentChar == 'C' && i < s.length() - 1 && (s.charAt(i + 1) == 'D' || s.charAt(i + 1) == 'M')) {result -= 100;} else {switch (currentChar) {case 'I':result += 1;break;case 'V':result += 5;break;case 'X':result += 10;break;case 'L':result += 50;break;case 'C':result += 100;break;case 'D':result += 500;break;case 'M':result += 1000;break;default:break;}}}return result;
}}
该算法直接根据题目中的规则进行逐个字符判断,并计算最终的整数结果。时间复杂度为O(n),其中n是给定的罗马数字字符串的长度。空间复杂度为O(1)。
LeetCode运行结果:

方法三:模拟减法
还有一种方法是基于模拟减法的思路来将罗马数字转换成整数。
具体的步骤如下:
-
初始化一个变量
result为0,表示最终的整数结果。 -
遍历给定的罗马数字字符串
s,从左往右逐个字符判断:-
如果当前字符的值比前一个字符的值大,则需要执行减法操作。将两个字符对应的值进行减法操作,并将结果加到
result上。注意,这里要通过减去两倍的前一个字符的值,来抵消之前被加上的值。 -
否则,直接将当前字符的值加到
result上。
-
-
返回
result作为最终的整数表示。
class Solution {
public int romanToInt(String s) {Map<Character, Integer> romanMap = new HashMap<>();romanMap.put('I', 1);romanMap.put('V', 5);romanMap.put('X', 10);romanMap.put('L', 50);romanMap.put('C', 100);romanMap.put('D', 500);romanMap.put('M', 1000);int result = 0;int prevValue = 0;for (int i = 0; i < s.length(); i++) {int value = romanMap.get(s.charAt(i));if (value > prevValue) {result += value - 2 * prevValue;} else {result += value;}prevValue = value;}return result;
}}
该算法通过模拟减法的操作来计算最终的整数结果。时间复杂度为O(n),其中n是给定的罗马数字字符串的长度。空间复杂度为O(1)。
LeetCode运行结果:

第二题
题目来源
14. 最长公共前缀 - 力扣(LeetCode)
题目内容

解决方法
方法一:水平扫描法
可以使用水平扫描法来查找字符串数组中的最长公共前缀。
具体的步骤如下:
1、初始化一个空字符串prefix,表示最长公共前缀。
2、如果输入的字符串数组为空或长度为0,则直接返回空字符串。
3、遍历字符串数组中的第一个字符串strs[0]的每个字符:
- 对于每个字符,遍历字符串数组中的其他字符串strs[i],其中i从1到n-1(n是字符串数组的长度)。
- 如果当前字符在其他字符串的相同位置上的字符不相等,或者其他字符串的长度小于等于当前位置,则表示不匹配,直接返回当前的公共前缀。
- 否则,将当前字符添加到prefix中。
4、返回prefix作为最长公共前缀。
class Solution {public String longestCommonPrefix(String[] strs) {if (strs == null || strs.length == 0) {return "";}String prefix = strs[0];for (int i = 1; i < strs.length; i++) {while (strs[i].indexOf(prefix) != 0) {prefix = prefix.substring(0, prefix.length() - 1);if (prefix.isEmpty()) {return "";}}}return prefix;
}}
该算法通过逐个字符比较字符串数组中的字符串来查找最长公共前缀。时间复杂度为O(mn),其中m是最长公共前缀的长度,n是字符串数组的长度。空间复杂度为O(1)。
LeetCode运行结果:

方法二:垂直扫描法
具体的步骤如下:
1、如果输入的字符串数组为空或长度为0,则直接返回空字符串。
2、遍历字符串数组中的每个字符的索引位置idx,从0到字符数组中最短字符串的长度-1:
- 对于每个索引位置idx,遍历字符串数组中的每个字符串strs[i],其中i从0到n-1(n是字符串数组的长度)。
- 如果当前索引位置超过了当前字符串的长度,或者当前字符在其他字符串的相同位置上的字符不相等,则表示不匹配,直接返回当前的公共前缀。
- 否则,将当前字符添加到最长公共前缀的末尾。
3、返回最长公共前缀作为结果。
class Solution {
public String longestCommonPrefix(String[] strs) {if (strs == null || strs.length == 0) {return "";}int minLength = getMinLength(strs);StringBuilder prefix = new StringBuilder();for (int idx = 0; idx < minLength; idx++) {char currentChar = strs[0].charAt(idx);for (int i = 1; i < strs.length; i++) {if (strs[i].charAt(idx) != currentChar) {return prefix.toString();}}prefix.append(currentChar);}return prefix.toString();
}private int getMinLength(String[] strs) {int minLength = Integer.MAX_VALUE;for (String str : strs) {minLength = Math.min(minLength, str.length());}return minLength;
}}
该算法通过逐个字符比较字符串数组中的字符串来查找最长公共前缀。时间复杂度为O(mn),其中m是最短字符串的长度,n是字符串数组的长度。空间复杂度为O(1)。
LeetCode运行结果:

方法三:分治法
具体的步骤如下:
- 如果输入的字符串数组为空或长度为0,则直接返回空字符串。
- 调用一个辅助函数longestCommonPrefixHelper,传入字符串数组和索引范围[0, n-1](n是字符串数组的长度)。
- 在longestCommonPrefixHelper函数中,如果起始索引等于结束索引,则返回当前字符串作为最长公共前缀。
- 将索引范围划分为两半,分别调用longestCommonPrefixHelper函数来获取左半部分和右半部分的最长公共前缀。
- 对左半部分和右半部分的最长公共前缀进行比较,取两者的最长公共前缀作为结果。
class Solution {
public String longestCommonPrefix(String[] strs) {if (strs == null || strs.length == 0) {return "";}return longestCommonPrefixHelper(strs, 0, strs.length - 1);
}private String longestCommonPrefixHelper(String[] strs, int start, int end) {if (start == end) {return strs[start];}int mid = (start + end) / 2;String leftPrefix = longestCommonPrefixHelper(strs, start, mid);String rightPrefix = longestCommonPrefixHelper(strs, mid + 1, end);return commonPrefix(leftPrefix, rightPrefix);
}private String commonPrefix(String str1, String str2) {int length = Math.min(str1.length(), str2.length());int i = 0;while (i < length && str1.charAt(i) == str2.charAt(i)) {i++;}return str1.substring(0, i);
}}
该算法使用递归地将字符串数组划分为更小的部分,最终求得最长公共前缀。时间复杂度为O(mnlogn),其中m是字符串的平均长度,n是字符串数组的长度。空间复杂度为O(logn),用于递归调用栈的额外空间。
LeetCode运行结果:

方法四:二分查找
具体的步骤如下:
- 如果输入的字符串数组为空或长度为0,则直接返回空字符串。
- 将最短的字符串作为起始点,将最长的字符串作为终止点。
- 计算起始点和终止点的中点mid。
- 判断从起始点到中点的字符串是否都是其他字符串的公共前缀。如果是,则继续在右半部分查找;否则,在左半部分查找。
- 重复步骤3和步骤4,直到起始点和终止点相等或者起始点大于终止点。
- 返回起始点和终止点相等的字符串作为结果。
class Solution {
public String longestCommonPrefix(String[] strs) {if (strs == null || strs.length == 0) {return "";}int minLength = getMinLength(strs);int start = 0, end = minLength - 1;while (start <= end) {int mid = (start + end) / 2;if (isCommonPrefix(strs, mid)) {start = mid + 1;} else {end = mid - 1;}}return strs[0].substring(0, (start + end + 1) / 2);
}private int getMinLength(String[] strs) {int minLength = Integer.MAX_VALUE;for (String str : strs) {minLength = Math.min(minLength, str.length());}return minLength;
}private boolean isCommonPrefix(String[] strs, int idx) {String prefix = strs[0].substring(0, idx + 1);for (int i = 1; i < strs.length; i++) {if (!strs[i].startsWith(prefix)) {return false;}}return true;
}}
该算法使用二分查找来逐步缩小最长公共前缀的范围,时间复杂度为O(mnlogm),其中m是最短字符串的长度,n是字符串数组的长度。空间复杂度为O(1)。
LeetCode运行结果:

第三题
题目来源
15. 三数之和 - 力扣(LeetCode)
题目内容

解决方法
方法一:双指针
可以使用双指针的方法来解决这个问题。首先,对数组进行排序,然后使用两个指针i和j来遍历数组。
具体的步骤如下:
- 对数组进行排序,确保数组是有序的。
- 遍历数组,对于每个元素nums[i],设置两个指针left和right分别指向i之后的开始和结束位置。
- 在left和right之间使用双指针法,寻找满足nums[i]+nums[left]+nums[right]==0的三元组。
- 如果找到满足条件的三元组,将其加入结果集。
- 跳过重复的元素,即如果nums[i]和nums[i-1]相等,则跳过当前循环。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result = new ArrayList<>();if (nums == null || nums.length < 3) {return result;}Arrays.sort(nums); // 排序数组for (int i = 0; i < nums.length - 2; i++) {if (i > 0 && nums[i] == nums[i - 1]) {continue; // 跳过重复的元素}int target = -nums[i];int left = i + 1, right = nums.length - 1;while (left < right) {int sum = nums[left] + nums[right];if (sum == target) {result.add(Arrays.asList(nums[i], nums[left], nums[right]));left++;right--;// 跳过重复的元素while (left < right && nums[left] == nums[left - 1]) {left++;}while (left < right && nums[right] == nums[right + 1]) {right--;}} else if (sum < target) {left++;} else {right--;}}}return result;
}
}
该算法的时间复杂度为O(n^2),其中n是数组的长度。排序的时间复杂度为O(nlogn),双指针的遍历时间复杂度为O(n^2)。空间复杂度为O(logn)或O(n),取决于排序算法的实现。最终返回的结果列表所占用的空间不计入空间复杂度。
LeetCode运行结果:

相关文章:
怒刷LeetCode的第6天(Java版)
目录 第一题 题目来源 题目内容 解决方法 方法一:哈希表 方法二:逐个判断字符 方法三:模拟减法 第二题 题目来源 题目内容 解决方法 方法一:水平扫描法 方法二:垂直扫描法 方法三:分治法 方…...
SSL双向认证-Nginx配置
SSL双向认证需要CA证书,开发过程可以利用自签CA证书进行调试验证。 自签CA证书生成过程:SSL双向认证-自签CA证书生成 Nginx配置适用于前端项目或前后端都通过Nginx转发的时候(此时可不配置后端启用双向认证) 1.Nginx配置&#…...
GO学习之 远程过程调用(RPC)
GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…...
八大排序(四)--------直接插入排序
本专栏内容为:八大排序汇总 通过本专栏的深入学习,你可以了解并掌握八大排序以及相关的排序算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:八大排序汇总 🚚代码仓库:小小unicorn的代码仓库…...
MYSQL--存储引擎和日志管理
存储引擎: 一、存储引擎概念: MySQL中的数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力,这些不同的技术以及配套的功能在MySQL中称为存储引擎。存储引擎是My…...
VUE之更换背景颜色
1. 确定需求 在实现之前,首先需要明确需求,即用户可以通过某种方式更改页面背景颜色,所以我们需要提供一个可操作的控件来实现此功能。 2. 创建Vue组件 为了实现页面背景颜色更换功能,我们可以创建一个Vue组件。下面是一个简单…...
大型集团借力泛微搭建语言汇率时区统一、业务协同的国际化OA系统
国际化、全球化集团,业务遍布全世界,下属公司众多,集团对管理方式和企业文化塑造有着很高的要求。不少大型集团以数字化方式助力全球统一办公,深化企业统一管理。 面对大型集团全球化的管理诉求,数字化办公系统作为集…...
Quartz 建表语句SQL文件
SQL文件在jar里面,github下载 https://github.com/quartz-scheduler/quartz/releases/tag/v2.3.2 解压,sql文件路径:quartz-core\src\main\resources\org\quartz\impl\jdbcjobstore tables_mysql_innodb.sql # # In your Quartz propertie…...
nginx SseEmitter 长连接
1、问题还原: 在做openai机器人时,后台使用 SseEmitterEventSource 实现流式获取数据,前端通过 EventSourcePolyfill 函数接收后端的数据,在页面流式输出到页面,做成逐字打稿的效果。本地测试后,可以正常获…...
若依cloud -【 100 ~ 】
100 分布式日志介绍 | RuoYi 分布式日志就相当于把日志存储在不同的设备上面。比如若依项目中有ruoyi-modules-file、ruoyi-modules-gen、ruoyi-modules-job、ruoyi-modules-system四个应用,每个应用都部署在单独的一台机器里边,应用对应的日志的也单独存…...
VPN协议是如何工作的
VPN,全名 Virtual Private Network,虚拟专用网,就是利用开放的公众网络,建立专用数据传输通道,将远程的分支机构、移动办公人员等连接起来。 VPN 通过隧道技术在公众网络上仿真一条点到点的专线,是通过利用…...
c++::作用域符解析
1)当存在具有相同名称的局部变量时,要访问全局变量 2)在类之外定义函数。 class A { } void A::func(){ }A a;a.func();3)访问一个类的静态变量 class A { static int b; } A::b; 4) 如果两个命名空间中都存在一个具有相同名称的类…...
【电源专题】什么是充电芯片的Shipping Mode(船运模式)
现在越来越多电子产品小型化,手持化,这样就需要电池来为产品供电。但电池供电造成的另一个难题就是产品的续航能力的强与弱。 如果想提升续航能力,有一种方法是提高电池容量。如果电池体积没有变化的情况下,可能使用了新型材料、高级技术来增加电池容量,但这势必会增加电池…...
WebGL笔记: 2D和WebGL坐标系对比和不同的画图方式, 程序对象通信,顶点着色器,片元着色器
WebGL 坐标系 canvas2d画布和webgl画布使用的坐标系都是二维直角坐标系,但它们坐标原点、y 轴的坐标方向,坐标基底都不一样canvas2d 坐标系的原点在左上角, x轴朝右,y轴朝下1个单位的宽就是一个像素的宽,1个单位的高就是一个像素…...
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
冒泡排序原理 每次比较两个相邻的元素,将较大的元素交换至右端 冒泡排序执行过程输出效果 冒泡排序实现思路 每次冒泡排序操作都会将相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足,就交换这两个相邻元素的次序&…...
多模块和分布式项目
一、什么是多模块项目 多模块项目是一种软件项目组织结构,其中一个大型项目被分成多个独立的子模块或子项目。每个子模块通常具有自己的功能、目录结构和开发周期,但它们可以协同工作以构建一个完整的应用程序。这种项目结构有助于提高代码的可维护性、…...
AI视频剪辑:批量智剪技巧大揭秘
对于许多内容创作者来说,视频剪辑是一项必不可少的技能。然而,传统的视频剪辑方法需要耗费大量的时间和精力。如今,有一种全新的剪辑方式正在改变这一现状,那就是批量AI智剪。这种智能化的剪辑方式能够让你在短时间内轻松剪辑大量…...
vue项目实现地址自动识别功能
1、安装第三方依赖 npm install address-parse 2、在需要使用的页面引入 import AddressParse from address-parse; 3、在页面上写入静态的html代码,可以输入地址,加上识别的输入框; <div class"auto_address"><van-…...
基于springboot财务管理系统springboot006
大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路…...
C语言-扫雷游戏的实现
🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
