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

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...

沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...