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

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...