LeetCode.12-整数转罗马数字符串(Integer to Roman)
这是悦乐书的第351次更新,第376篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Medium级别的第6题(顺位题号是12)。罗马数字由七个不同的符号表示:I,V,X,L,C,D和M.
符号 值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如,2用罗马数字写成II
,由两个I加在一起。12写为XII
,简称为X + II
。
27写成XXVII
,即XX + V + II
。
罗马数字通常从左到右从最大到最小。但是,四个数字不是IIII
。相反,4写为IV
。
因为I
在V
之前,我们做减法得到4。同样的原则适用于9,9被写为IX
。有六个使用减法的实例:
I
可以放在V
(5)和X
(10)之前,得到4和9。
X
可以放在L
(50)和C
(100)之前,得到40和90。
C
可以放在D
(500)和M
(1000)之前,得到400和900。
给定一个整数,将其转换为罗马数字。输入保证在1到3999的范围内。例如:
输入:3
输出:“III”
输入:4
输出:“IV”
输入:9
输出:“IX”
输入:58
输出:“LVIII”
说明:L = 50,V = 5,III = 3。
输入:1994
输出:“MCMXCIV”
说明:M = 1000,CM = 900,XC = 90,IV = 4。
02 第一种解法
题目要求我们将整数转成罗马数字符串来表示,和之前遇到的罗马数字符串转整数正好相反。
题目限定了num的范围,[1,3999]
,针对常见的数字,列了下面这些罗马数和整数的对应关系:
900 CM 90 XC 9 IX
800 DCCC 80 LXXX 8 VIII
700 DCC 70 LXX 7 VII
600 DC 60 LX 6 VI
500 D 50 L 5 V
400 CD 40 XL 4 IV
3000 MMM 300 CCC 30 XXX 3 III
2000 MM 200 CC 20 XX 2 II
1000 M 100 C 10 X 1 I
我们可以将他们的对应关系分为4组:
第一组,最高位小于4,他们对应的罗马数是叠加的,例如1000是M,3000是
MMM
。第二组,最高位等于4,他们对应的罗马数是在以5开头罗马数前加上以1开头的罗马数,且两者是相邻的关系。
第三组,最高位在5到8之间,对应的罗马数是以5开头的罗马数为基础,后跟上叠加的1开头的罗马数,两者也是相邻的关系。
第四组,最高为等于9,对应的罗马数是以1开头的罗马数间隔组合,例如900,在代表1000的
M
前加代表100的C
,即CM
,两者中间间隔一位。
根据以上的对应关系组合,我们将不同整数、罗马数字符串初始化为数组,由高位到低位,依次计算罗马数。
public String intToRoman(int num) {
String[] roman = {"M", "D", "C", "L", "X", "V", "I"};
int[] value = {1000, 500, 100, 50, 10, 5, 1};
StringBuilder sb = new StringBuilder();
for (int i=0; i<value.length; i+=2) {
// 得到当前num的最高位
int tem = num/value[i];
if (tem < 4) {
// 叠加
for (int j=0; j<tem; j++) {
sb.append(roman[i]);
}
} else if (tem == 4) {
// 相邻
sb.append(roman[i]+roman[i-1]);
} else if (tem > 4 && tem < 9) {
// 相邻
sb.append(roman[i-1]);
for (int j=6; j<=tem; j++) {
sb.append(roman[i]);
}
} else if (tem == 9) {
// 间隔两位
sb.append(roman[i]+roman[i-2]);
}
// 去掉已经参与计算的高位
num = num%value[i];
}
return sb.toString();
}
03 第二种解法
在第一种解法的基础上,我们将初始数组中的元素分别对应增加了6位,以9和4开头。依旧是从高位往低位计算,与第一种解法中利用取余、取整不同,此解法是循环做减法,直到num剩下的值小于当前需要减去的值,才会寻找下一个需要减去的数。
public String intToRoman2(int num) {
String[] roman = {"M", "CM", "D", "CD", "C", "XC",
"L", "XL", "X", "IX", "V", "IV", "I"};
int[] value = {1000, 900, 500, 400, 100, 90,
50, 40, 10, 9, 5, 4, 1};
StringBuilder sb = new StringBuilder();
for (int i=0; i<value.length; i++) {
while (num >= value[i]) {
sb.append(roman[i]);
num -= value[i];
}
}
return sb.toString();
}
04 第三种解法
还有一种取巧的解法。因为题目限定num的范围,最高不会超过4000,我们可以把num拆成4个部分,千位只有四种可能,0(num是一个三位数)、1、2、3,百位对应的有10种可能,0到9,十位和个位也是10种可能,只需要将他们都列出来,依次取num中不同位对应的字符串即可。
此解法的时间复杂度是O(1)
。
public static String intToRoman3(int num) {
String M[] = {"", "M", "MM", "MMM"};
String C[] = {"", "C", "CC", "CCC", "CD",
"D", "DC", "DCC", "DCCC", "CM"};
String X[] = {"", "X", "XX", "XXX", "XL",
"L", "LX", "LXX", "LXXX", "XC"};
String I[] = {"", "I", "II", "III", "IV",
"V", "VI", "VII", "VIII", "IX"};
return M[num/1000] + C[(num%1000)/100] +
X[(num%100)/10] + I[num%10];
}
05 小结
算法专题目前已连续日更超过六个月,算法题文章219+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode.12-整数转罗马数字符串(Integer to Roman)的更多相关文章
- [LeetCode] 12,13 整数和罗马数互转
12. 整数转罗马数字 题目链接:https://leetcode-cn.com/problems/integer-to-roman/ 题目描述: 罗马数字包含以下七种字符: I, V, X, L,C ...
- Java实现 LeetCode 12 整数转罗马数字
12. 整数转罗马数字 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 ...
- leetcode 12 整数转罗马数字 贪心
额,连着两个贪心? 这是局部最优问题:能用大"罗马数表示"就不会用小的. 先构造出所有基础罗马数,然后从大到小比较 因为比较的只有1000,900,...有限并有些麻烦,构造tab ...
- LeetCode 12. 整数转罗马数字(Integer to Roman)
题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II , ...
- LeetCode(12. 整数转罗马数字)
问题描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II , ...
- LeetCode 12 - 整数转罗马数字 - [简单模拟]
题目链接:https://leetcode-cn.com/problems/integer-to-roman/ 题解: 把 $1,4,5,9,10,40,50, \cdots, 900, 1000$ ...
- 【LeetCode】12. Integer to Roman 整型数转罗马数
题目: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from ...
- 《LeetBook》leetcode题解(12):Integer to Roman[M]
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- LeetCode:整数转罗马数字【12】
LeetCode:整数转罗马数字[12] 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 10 ...
随机推荐
- mysql dump出source进去时报1046
我这边主要是备注里有 ; 号标记,所以在执行时应该会有问题,改成中文:的 出现这个问题可以打开sql文件,看看错误的点, 大胆尝试
- C++ 编码导致编译错误
记录一个问题 平时经常用Notepad++写C++,然后g++编译 最近出现一个莫名其妙的问题 原来是编译时遇到了非法字符 用Notepad++一看,原来文件的编码出现的变化 不是UTF-8或者其他对 ...
- python算数、逻辑运算,位运算
算术运算符 对变量和数组进行算术运算. 算术运算符:+,-,*,/,% +:将连个或者多个数值相加 -:将两个数值相减 *:将两个数值相乘 /:将两个数值相除 %:取相除的余数 赋值运算符 将右边的值 ...
- hibernate中Session的load和get方法的区别是什么?
主要有以下三项区别: ① 如果没有找到符合条件的记录,get方法返回null,load方法抛出异常. ② get方法直接返回实体类对象,load方法返回实体类对象的代理. ③ 在Hibernat ...
- qt5-QWidget坐标系统和大小和展示区域
#include "win.h" #include <QPushButton> #include <QLabel> #include <QDebug& ...
- 【leetcode】1234. Replace the Substring for Balanced String
题目如下: You are given a string containing only 4 kinds of characters 'Q', 'W', 'E' and 'R'. A string i ...
- [人物存档]【AI少女】【捏脸数据】写实系列
点击下载:AISChaF_20191023202713797.zip 点击下载:AISChaF_20191023202713797.zip
- CSS3的2D 转换——旋转,缩放,translate(),skew(),matrix()
2D转换方法:在平面对元素进行旋转,缩放,移动,拉伸. ㈠浏览器支持 ⑴2D转换效果有以下的浏览器支持: ⑵在编辑代码的时候要注明用哪种浏览器打开,在前面加上前缀,下面是编辑器的简写形式,以及前缀 ...
- ABI与ARM,X86的概念
Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2 ...
- Make文件(一)
基本规则: 目标:依赖 (tab)规则 目标:需要生成的目标文件 依赖:生成该目标所需的一些文件 规则:由依赖文件生成目标文件的手段 tab:每条规则前必须以tab开头,使用空格不行. 例如: /** ...