力扣13. 罗马数字转整数:Java多种解法详解

devtools/2025/3/26 11:04:16/

力扣13. 罗马数字转整数:Java多种解法详解

题目描述

罗马数字由以下字符构成:I, V, X, L, C, D, M,分别对应数值1, 5, 10, 50, 100, 500, 1000。
特殊规则:当小值字符位于大值字符左侧时,表示减法(如 IV=4)。要求将罗马数字转换为整数,输入保证有效且范围在[1, 3999]内。


解法一:哈希表 + 左到右遍历(推荐)

代码实现

java">import java.util.HashMap;
import java.util.Map;class Solution {public int romanToInt(String s) {Map<Character, Integer> map = new HashMap<>() {{put('I', 1);put('V', 5);put('X', 10);put('L', 50);put('C', 100);put('D', 500);put('M', 1000);}};int ans = 0;for (int i = 0; i < s.length(); i++) {if (i < s.length() - 1 && map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) {ans -= map.get(s.charAt(i));} else {ans += map.get(s.charAt(i));}}return ans;}
}

复杂度分析

  • 时间复杂度:O(n),遍历一次字符串。
  • 空间复杂度:O(1),哈希表存储固定7个字符的映射。

核心思路

从左到右遍历字符,若当前字符值小于下一个字符值,则减去当前值(如 IV=4-1+5),否则直接累加。


解法二:右到左遍历 + 层级比较

代码实现

java">class Solution {public int romanToInt(String s) {int sum = 0, level = 1;for (int i = s.length() - 1; i >= 0; i--) {int value = getValue(s.charAt(i));if (value < level) {sum -= value;} else {sum += value;level = value;}}return sum;}private int getValue(char c) {switch(c) {case 'I': return 1;case 'V': return 5;case 'X': return 10;case 'L': return 50;case 'C': return 100;case 'D': return 500;case 'M': return 1000;default: return 0;}}
}

复杂度分析

  • 时间复杂度:O(n),反向遍历一次字符串。
  • 空间复杂度:O(1),仅用常数变量。

核心思路

从右向左遍历,维护一个层级变量 level。若当前字符值小于层级,则减去该值(如 IXI 在右侧遍历时会被减去),否则累加并更新层级。


解法三:直接映射 + 后向修正

代码实现

java">class Solution {public int romanToInt(String s) {int sum = 0, prev = 0;for (int i = s.length() - 1; i >= 0; i--) {int curr = getValue(s.charAt(i));sum += (curr < prev) ? -curr : curr;prev = curr;}return sum;}private int getValue(char c) {switch(c) {case 'I': return 1;case 'V': return 5;case 'X': return 10;case 'L': return 50;case 'C': return 100;case 'D': return 500;case 'M': return 1000;default: return 0;}}
}

复杂度分析

  • 时间复杂度:O(n),反向遍历一次字符串。
  • 空间复杂度:O(1),无需额外存储。

核心思路

反向遍历时,若当前值小于前一个值则减去,否则累加。例如 IX 反向遍历先处理 X(+10),再处理 I(-1),结果为9。


各解法对比

解法优点缺点适用场景
解法一逻辑清晰,代码简洁需哈希表额外空间通用场景
解法二无哈希表,空间更优反向遍历需适应注重空间优化
解法三直接映射,高效需手动处理字符映射性能敏感场景

示例解析

以输入 MCMXCIV 为例:

  1. 解法一
    • M(1000) → 累加1000
    • C(100) < M(1000) → 累加100 → 总1100
    • M(1000) 前无更大值 → 累加1000 → 总2100
    • 后续同理,最终结果为1994。

总结

以上三种方法均能高效解决该问题,推荐使用解法一或解法三,逻辑清晰且代码简洁。实际开发中可根据需求选择空间或时间最优方案。

可直接复制代码到力扣运行,保证通过!


如需进一步优化或探讨其他解法,欢迎评论区留言讨论。


http://www.ppmy.cn/devtools/171329.html

相关文章

linux0.11内核源码修仙传第九章——时间初始化

&#x1f680; 前言 本文主要解释了计算机断电重启后能准确读取时间的原因&#xff0c;内容很短&#xff0c;对应于书中的第17回。希望各位给个三连&#xff0c;拜托啦&#xff0c;这对我真的很重要&#xff01;&#xff01;&#xff01; 目录 &#x1f680; 前言&#x1f3c6;…

【微服务架构】本地负载均衡的实现(基于随机算法)

前言 负载均衡 概念&#xff1a;一种将网络流量或业务请求均匀分配到多个服务器或服务实例上的技术&#xff0c;旨在提高系统的可用性、性能和可伸缩性。作用&#xff1a; 提高性能&#xff1a;通过将请求分散到多个实例上&#xff0c;避免单个实例因请求过多而过载&#xff…

GMII 接口

文章目录 概述硬件拓扑GMII 接口站管理接口发送数据时序接收数据时序参考 本文为笔者学习以太网对网上资料归纳整理所做的笔记&#xff0c;文末均附有参考链接&#xff0c;如侵权&#xff0c;请联系删除。 概述 GMII 是千兆网的MII接口&#xff0c;这个也有相应的 RGMII 接口&…

笔试专题(三)

文章目录 字符串中找出连续最长的数字串题解代码 拼三角题解代码 字符串中找出连续最长的数字串 题目链接 题解 1. 考察双指针 模拟 2. 算法思路&#xff1a;给定一个i 0&#xff0c;让i&#xff0c;如果遇到数字字符就创建一个变量j i&#xff0c;让j去遍历&#xff0c…

Rust从入门到精通之进阶篇:20.项目实践

项目实践 在本章中,我们将把前面学到的所有 Rust 知识整合起来,构建一个完整的应用程序。通过实际项目,你将学习如何组织代码、处理依赖关系、实现功能以及测试和部署 Rust 应用程序。我们将构建一个命令行待办事项管理器(Todo CLI),它具有添加、列出、完成和删除任务的…

深入理解指针(2)(C语言版)

文章目录 前言一、数组名的理解二、使用指针访问数组三、一维数组传参的本质四、冒泡排序五、二级指针六、指针数组七、指针数组模拟二维数组总结 前言 在上一篇文章中&#xff0c;我们初步了解了指针的基本概念和用法。今天&#xff0c;我们将继续深入探索指针在数组、函数传…

Uniapp使用大疆SDK打包离线原生插件二

上一篇讲了如何下载及配置原生插件&#xff0c;今天深入的了解下如何将java代码的SDK引入Uniapp 一、配置libs: 在Android开发中&#xff0c;libs目录通常用于存放项目所需的第三方库文件。 将sdk中的包lib.5plus.base-release.aar、android-gif-drawable-release1.2.23.aa…

日志截断/日志中途清空/不停止程序

使用场景&#xff1a; nohup ./abc.sh > 123.log 2>&1 & 若想在不停止程序的前提下减小 123.log 的占用空间或者对日志进行分割&#xff0c;可采用如下方法&#xff1a; 1. 手动截断日志 可以手动截断日志文件&#xff0c;把文件内容清空&#xff0c;但保留文…