怒刷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首发🐒 如…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...