Roman to Integer/Integer to Roman

Roman to Integer完整代码 leetcode上Roman to Integer的完整C++代码,已被accepted 立即下载

1 Roman to Integer

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.

首先,想做出这道题得了解一下罗马数字。罗马数字有如下符号:

  • I(1)
  • V(5)
  • X(10)
  • L(50)
  • C(100)
  • D(500)
  • M(1000)

【左减右加】如果当前比前一个大,说明这一段的值应该是当前这个值减去前面记录下的临时变量中的值。比如IIV = 5 – 2。 如果当前比前一个小,那么就可以先将临时变量的值加到结果中,然后开始下一段记录。比如VI = 5 + 1。

【右加连续的数字重复不得超过三次,左减的数字只有一个】VIII = 8,但9用IX表示,而不是VIIII。900 用 CM 表示,800 用 DCCC 表示,而不是 CCM。

【大的数字在左边】对于MCMXCVI,我们可以很快把它分解成M + CM + XC + VI,即1000 + (1000-100) + (100-10) + (5+1) = 1996。为什么知道这样分解?

1.1 一般思路

由于此题只考虑1 to 3999,所以我们可以这样理解:罗马数字没有进位制,它仅仅是几个基本字母所代表的数字的和而已,所以,罗马数字总体上是在做加法,只是有一个【左减】的特殊情况。【左减】的模式是什么?【小 大】,如例子中的 CM 、 XC。

所以,我们从左往右遍历,如果当前字母(的数值)与后一个字母相等或是大于的话,则加上当前字母的值,开始判断一个字母:
DCCC,curr = D,next = C,D > C, num 加上D,i++开始判断C的情况。

如果当前字母小于后一个字母,则看是【小 大】的特殊情况,num加上(next - curr)的值,i+2:
MDMV,curr = D,next = M, D < M,num + (M - D),i+2,跳过M,判断V的情况。

这一段逻辑的代码为:

        if(s.length() == 1)
            return toNumber(s.charAt(0));
        int num = 0;
        int curr, next;
        for(int i=0; i<s.length()-1;){
            curr = toNumber(s.charAt(i));
            next = toNumber(s.charAt(i+1));
            //   大 小
            if(curr >= next){
                num += curr;
                i++;
            }
            //  小 大
            else {
                num += (next - curr);
                i += 2;
            }
        }

但是这个逻辑有一个问题,我们每次都是以curr为核心,判断curr与next的关系。如果取到数组的末尾,也就是最后两个数字,如果是【大小 大】的情况那还好,两个会结合在一起运算;如果是【大 小】或是【相等】,结果num只会加上倒数第二个的值,最后一个字母没法判断了,所以,我们还得对数组的末尾两个字母做额外的判断:

        int last = toNumber(s.charAt(s.length()-1));
        int last2 = toNumber(s.charAt(s.length()-2));
        if(last <= last2){
            num += last;
        }

1.2 代码改进

上面的思路是不是有点繁琐?

其实这就又归结为数组的边界处理问题了。在需要用到数组的算法题中,我们每次都要格外小心数组为空,数组只有一个元素,和数组边界的问题。

既然从第一个元素开始遍历,每次判断它与下一个元素的方式,在末尾不可避免地要多做一次判断,那么我们很自然地可以想到换一种思路:从第二个元素开始遍历,每次判断它与前一个元素的关系。接下来,我们试一试这种思路是否可行,不行的话就算了。

还是拿 MCMXCVI 举例。从第二个数字C开始判断:

  • MC, pre = M,curr = C,【大 小】的关系,所以num加上curr。
  • CM, pre = C, curr = M,【小 大】的特殊关系,理应num加上(curr - pre),但是前面错误地将C加了一次了,所以修正为加上(curr - 2 * pre)。
  • MX,【大 小】,加上X。
  • XC,【小 大】,加上(C - 2*X)。
  • CV,【大 小】,加上V。
  • VI,【大 小】,加上I。

对于首字母我们怎么处理呢?上面的例子中,首字母M之间加上去就好了,那么我们再来看看特殊情况是不是也可以这样。以IV(4)举例,首字母直接加上,num = 1;判断IV为【小 大】,num + (V - 2 * I),结果正确,可以。所以代码为:

        int num = toNumber(s.charAt(0));
        int pre, curr;
        for(int i=1; i<s.length(); i++){
            curr = toNumber(s.charAt(i));
            pre = toNumber(s.charAt(i-1));
            if( curr > pre){
                num += (curr - 2 * pre);
            }
            else {
                num += curr;
            }
        }

这种思路不仅不用额外地考虑边界问题,而且意外地,我发现它还不用额外地去判断罗马数字只有一个字母的情况。

1.3 方法三

从右王左遍历:

        int num = toNumber(s.charAt(s.length()-1));
        //从右往左遍历
        int curr, pre;
        for(int i= s.length()-2; i>=0;i--){
            curr = toNumber(s.charAt(i));
            pre = toNumber(s.charAt(i+1));
            if(curr < pre){
                num -= curr;
            }
            else {
                num += curr;
            }
        }

2 Integer to Roman

在一开始我就举了一个例子:对于MCMXCVI,我们可以很快把它分解成M + CM + XC + VI,即1000 + (1000-100) + (100-10) + (5+1) = 1996。

在来一个:MDCCCLXXXIV = M + DCCC + LXXX + IV = 1000 + 800 + 80 + 4 = 1884。

发现规律没有? 现在十进制在人类世界占主流是有一定原因的,可以因为它符合人类的大脑内部回路吧。罗马数字毕竟也是人类为生产生活创造的,所以它和十进制的联系还是比较直观的。

  • 1~9: {“I”, “II”, “III”, “IV”, “V”, “VI”, “VII”, “VIII”, “IX”};

  • 10~90: {“X”, “XX”, “XXX”, “XL”, “L”, “LX”, “LXX”, “LXXX”, “XC”};

  • 100~900: {“C”, “CC”, “CCC”, “CD”, “D”, “DC”, “DCC”, “DCCC”, “CM”};

  • 1000~3000: {“M”, “MM”, “MMM”}.

1996 转 罗马数字: 1996 = 1000 + 900 + 90 + 6 = M + CM + XC + VI。

好了,现在可以直接贴代码了:

public class Solution {
    public String intToRoman(int num) {
        //纬度1:0个、1十、2百、3千
        //纬度2:0-9,其中0没有用
        String[][] roman = {  
                {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"},  
                {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},  
                {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},  
                {"", "M", "MM", "MMM"}  
            };
        String s="";
        int mod;
        int d = 0;
        while(num != 0){
            mod = num % 10;
            s = roman[d][mod] + s;
            d++;
            num /= 10;
        }
        return s;
    }
}
Open3D——RANSAC 三维点云空间直线拟合【2025最新版】 使用RANSAC算法在点云数据中拟合三维空间直线的python代码实现。博客长期更新,本文最新更新时间为:2025年3月23日。 阅读详情

相关推荐

机器学习教程 之 半监督学习 Co-training 协同训练 (论文、算法、数据集、代码)

这篇博客介绍的是一篇用于半监督分类问题的方法: 协同训练 Co-training, A. Blum and T. Mitchell, “Combining labeled and unlabeled data with co-training,” in Proc. of the 11th Annual Conf. on Computational Learning Theory, 1998.,这算是半监督领域里面始祖级的论文了,是1998年两位CMU大佬提出的方法。 之前还写过一篇关于Tri-trainin

冯良骏 的 博客 1万+

罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12...

qq_45067089的博客 280

EM4095低频RFID曼彻斯特解码实战:从原理图到MCU代码实现

本文详细介绍了EM4095低频RFID读卡器的设计与实现,从芯片工作原理、天线设计到曼彻斯特解码算法。重点讲解了基于STM32的MCU代码实现,包括定时器捕获、数字滤波和错误处理,为开发125kHz RFID系统提供实用指南。

oil88的博客 713

LeetCode:Roman to Integer - 罗马数字到阿拉伯数字的转换

1、题目名称 Roman to Integer (罗马数字到阿拉伯数字的转换) 2、题目地址 https://leetcode.com/problems/roman-to-integer/ 3、题目内容 英文:Given a roman numeral, convert it to ...

234

别再只用固定线了!聊聊Android车机‘快速倒车’与‘正常倒车’的UI与数据流核心差异(附动态轨迹线实现原理)

本文深度解析Android车机中快速倒车与正常倒车的核心差异,探讨从内核级视频流水线到动态轨迹线的技术实现。快速倒车通过内核直接操作FrameBuffer实现2秒内响应,而正常倒车则支持多传感器数据融合与动态UI元素。文章还分享了动态轨迹线的算法实现与性能优化技巧,帮助开发者打造极致的倒车体验。

weixin_42550597的博客 253

智能驾驶小白必看:MEB低速紧急制动系统的工作原理与传感器配置详解

本文深入解析了MEB低速紧急制动系统的工作原理与传感器配置。该系统作为智能驾驶的关键安全冗余,专为应对停车场、拥堵路段等复杂低速场景设计。文章详细拆解了其如何通过超声波雷达、环视摄像头等传感器融合感知环境,并基于碰撞时间(TTC)等模型进行风险评估与分级制动,最终实现主动防碰撞,是智能驾驶技术实用化的重要体现。

c2d3e4f的博客 1130

LeetCode题库 13罗马数字转整数(java)

罗马数字包含以下七种字符:I,V,X,L,C,D和M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做II,即为两个并列的 1。12 写做XII,即为X+II。 27 写做XXVII, 即为XX+V+II。 通常...

mcp3128 1186

从标记基因到功能分析:手把手教你人工注释单细胞亚群的完整流程

本文详细介绍了人工注释单细胞亚群的完整流程,从标记基因筛选到功能分析验证,特别针对肿瘤微环境、发育轨迹等复杂场景提供解决方案。通过差异表达分析、多维数据整合和实验验证,帮助研究者准确识别细胞类型,提升单细胞转录组研究的生物学解读深度。

jenkins8butler的博客 244

罗马数字

描述 Description 一类书的序言是以罗马数字标页码的。传统罗马数字用单个字母表示特定的数值,以下是标准数字表:  I 1  L 50  M 1000 V 5  C 100 X 10 D 500 最多3个同样的可以表示为10n的数字(I,X,C,M)可以连续放在一起,表示它们的和:  III=3 CCC=300 可表示为5x10n的字符(V,L,D)从不连续出现。 

23333333 1220

SAP PFCG 中的单一角色与复合角色

在 SAP 系统的安全与授权管理中,事务码 PFCG(角色维护)扮演着关键角色。理解单一角色(Single Role)和复合角色(Composite Role)的概念,对于有效地管理用户权限至关重要。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1476

让 RAP 弹窗参数真正变成必填:Excel Upload Action 的两种实现路径

摘要 在RAP应用中,action弹窗参数经常缺乏必填校验,导致用户体验差。本文提出两种解决方案:1)在action实现中手动校验,简单但交互不流畅;2)通过root abstract entity和abstract BDEF建模,利用field(mandatory)实现框架级校验,推荐此长期方案。后者将约束集中到模型层,使UI与执行期校验一致,特别适合ABAP Cloud环境。以Excel导入为例,强制填写备注和明确选择试运行,可避免审计问题,提升系统可靠性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 196

roman-to-integer/integer-to-roman

【题目描述】Given a roman numeral, convert it to an integer.Input is guaranteed to be within the range from 1 to 3999. 【解题思路】知道罗马数的规则,其实是不难的 罗马数字是阿拉伯数字传入之前使用的一种数码。罗马数字采用七个罗马字母作数字、即Ⅰ(1)、X(10)、C(100)、M(1000)、...

weixin_36909758的博客 202

C/C++基础讲解(四十三)之图形篇之绘制直线、圆、圆弧、 椭圆

程序主要是基于Visual studio 2019进行编译完成了,有兴趣的小伙伴可以自己安装下Visual studio 2019,网上有现成的教程,当然了,如果有问题,也可以和我联系,这里我们主要讲解些源码实例,不多说了,言归正传。 C语言,做为学习其他语言的基础语言,其重要性就不言而喻了.下面我将和大家一起来学习探讨C语言的相关奥秘。 实例1:绘制直线 实例2:绘制圆 实例2:绘制圆弧 实例2:绘制椭圆

hnjzfwy的博客 1234

刷leetcode:Roman to Integer/ Integer to Roman

public class Solution { public int romanToInt(String s) { /** Map hashMap=new HashMap(); hashMap.put("I",1); hashMap.put("V",5); hashMap.put("X",10); hashMap.put("L",50); hashM

Renxiao的专栏 381

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

[LeetCode/LinkedIn] Integer to Roman and roman number to Integer

I = 1; V = 5; X = 10; L = 50; C = 100; D = 500; M = 1000; 其中每两个阶段的之间有一个减法的表示,比如900=CM, C写在M前面表示M-C。public String intToRoman(int num) { String roman; String[] symbol = {"M","CM","D","CD",

Pushing Code 863

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

LeetCode12~14 Integer to Roman/Roman to Integer/Longest Common Prefix

一:Integer to Roman 题目: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. 链接:https://leetcode.com/problems/integer-to-roman/ 分析:此题

小村长技术blog 1128

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

<LeetCode OJ> 13 / 12 Roman to Integer & Integer to Roman

Roman to Integer My Submissions Question Total Accepted: 64343 Total Submissions: 175540 Difficulty: Easy Given a roman numeral, convert it to an integer. Input is guaranteed to b

EbowTang的练习场 1115

Leetcode - String - Roman to Integer/Integer to Roman

1、Roman to Integer

小熊糖否——木子兮的自留地 386

leetcode/roman to integer

如今我们最常见的罗马数字就是钟表的表盘符号:Ⅰ,Ⅱ,Ⅲ,Ⅳ(IIII),Ⅴ,Ⅵ,Ⅶ,Ⅷ,Ⅸ,Ⅹ,Ⅺ,Ⅻ…… 对应阿拉伯数字(就是现在国际通用的数字),就是1,2,3,4,5,6,7,8,9,10,11,12。(注:阿拉伯数字其实是古代印度人发明的,后来由阿拉伯人传入欧洲,被欧洲人误称为阿拉伯数字。)     基本字符 I V X

jiangxxonline的专栏 501

[Leetcode][python]Roman to Integer/罗马数字转整数

题目大意将罗马数字转为整数解题思路与上一题不同,这一题可以使用dict。来自:Gitbook 根据罗马数字的规则,只有在前面的字母比当前字母小的情况下要执行减法,其他情况只需要把罗马字母对应的数字直接相加即可。如果发现前一个字母比当前字母小,就减去前一个字母,因为错误的把它加入了结果,且在加上当前字母时还要减去前一个字母的值。代码class Solution(object): def ro

蛮三刀酱 727

leetcode做题总结,题目Integer to Roman 2012/01/15

今天发现一个问题,人家是leetcode被我yi'zhi

sdadssa1的专栏 356

[LeetCode] 012. Integer to Roman (Medium) (C++/Java/Python)

[LeetCode] 012. Integer to Roman (Medium) (C++/Java/Python)

水果君の日常 2942

[LeetCode] 013. Roman to Integer (Easy) (C++/Java/Python)

[LeetCode] 013. Roman to Integer (Easy) (C++/Java/Python)

水果君の日常 3716

【LeetCode013算法/编程练习C++】Roman to Integer //难得击败了80%的人

罗马数字转整数int

朱铭德的博客 1717

LeetCode 13.Roman to Integer(罗马数字转整数) 数学,字符串/easy

文章目录1.Description2.Example3.Solution优化: 1.Description 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12

押切徹的博客 339
上一篇: Reverse Linked List
下一篇: Number of 1 Bits
奋起直追CDS
博客等级 码龄11年 57粉丝 94原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值