12. Integer to Roman

  • Total Accepted: 71315
  • Total Submissions: 176625
  • Difficulty: Medium

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

思路:

首先,我们得弄清楚罗马数字的计数方式。根据维基百科的介绍:https://zh.wikipedia.org/wiki/%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97

  罗马数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。按照下述的规则可以表示任意正整数。需要注意的是罗马数字中没有“0”,与进位制无关。一般认为罗马数字只用来记数,而不作演算。

  • 重复数次:一个罗马数字重复几次,就表示这个数的几倍。
  • 右加左减

    • 在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。
    • 在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
    • 左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
    • 但是,左减时不可跨越一个位值。比如,99不可以用IC({\displaystyle 100-1})表示,而是用XCIX({\displaystyle [100-10]+[10-1]})表示。(等同于阿拉伯数字每位数字分别表示。)
    • 左减数字必须为一位,比如8写成VIII,而非IIX。
    • 右加数字不可连续超过三位,比如14写成XIV,而非XIIII。(见下方“数码限制”一项。)
  • 加线乘千:

    • 在罗马数字的上方加上一条横线或者加上下标的Ⅿ,表示将这个数乘以1000,即是原数的1000倍。
    • 同理,如果上方有两条横线,即是原数的1000000({\displaystyle 1000^{2}})倍。
  • 数码限制:

    • 同一数码最多只能连续出现三次,如40不可表示为XXXX,而要表示为XL。

方案一  

  从根据红色标红的规则,我们知道在个十百千每一位上的数值肯定是只与对应位上的表达形式有关,而不会牵扯到前一位或后一位上。eg:在十位的表达上有X、XX、XXX、XL、L、LX、LXX、LXXX、XC,而个位和百位对应的表达也都有对应的,完全不会影响到十位上对应的表达。所以,只要整数的十位数值为6,则对应表达式一定是千位+LX+各位。

  所以,就是直接列举出个十百千每一位的表现形式,然后我们计算每一位的数值,用对应的字符串去填充就可以了,特殊的一点事罗马数中没有数值0,所以我们给其对应的为空字符串表示。所以有:

  【罗马数字】

    个位上的0~9: {"","I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};

    十位上的0~9: {"","X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};

    百位上的0~9: {"","C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};

    千位上的0~3: {"","M", "MM", "MMM"}.

  所以,代码如下:

 public String intToRoman(int num) {
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 res = "";
int digit = 0;
while (num != 0) {
int remain = num % 10;
res = roman[digit][remain] + res;
digit++;
num /= 10;
}
return res;
}

方案二

  根据上面蓝色标注的部分,我们可以知道,在减数的时候有特定的规律,就是只能减1位且不能跨越一个位数,同时只限于I X C。像上面那个例子,99 不能用IC(100-1)表示,是因为如果一个数字超过90(或等于90),其罗马数字的表示就必须包含一个XC(100-10)。

同理,对I X C都适用这个原则。

  这个判断,要从最大往下找,如果一个数字是5,那么他就是属于大于等于5,罗马数字包含V,而无需写成IIIII。所以,可以写成递归的方式,代码可以写成如下(代码源自http://www.cnblogs.com/springfor/p/3886459.html):

 public String intToRoman(int num) {
if(num>=1000) return "M"+intToRoman(num-1000);
if(num>=900) return "CM"+intToRoman(num-900);
if(num>=500) return "D"+intToRoman(num-500);
if(num>=400) return "CD"+intToRoman(num-400);
if(num>=100) return "C"+intToRoman(num-100);
if(num>=90) return "XC"+intToRoman(num-90);
if(num>=50) return "L"+intToRoman(num-50);
if(num>=40) return "XL"+intToRoman(num-40);
if(num>=10) return "X"+intToRoman(num-10);
if(num>=9) return "IX"+intToRoman(num-9);
if(num>=5) return "V"+intToRoman(num-5);
if(num>=4) return "IV"+intToRoman(num-4);
if(num>=1) return "I"+intToRoman(num-1);
return "";
}

非递归方式如下:

 public String intToRoman(int num) {
String str = "";
String [] symbol = {"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};
for(int i=0;num!=0;i++){
while(num >= value[i]){
num -= value[i];
str += symbol[i];
}
}
return str;
}

LeetCode--No.012 Integer to Roman的更多相关文章

  1. 【LeetCode】012. Integer to Roman

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

  2. 《LeetBook》leetcode题解(12):Integer to Roman[M]

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  3. No.012 Integer to Roman

    12. Integer to Roman Total Accepted: 71315 Total Submissions: 176625 Difficulty: Medium Given an int ...

  4. 【LeetCode】12. Integer to Roman (2 solutions)

    Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within t ...

  5. 【JAVA、C++】LeetCode 012 Integer to Roman

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

  6. [Leetcode]012. Integer to Roman

    public class Solution { public String intToRoman(int num) { String M[] = {"", "M" ...

  7. 【一天一道LeetCode】#12 Integer to Roman

    一天一道LeetCode系列 (一)题目 Given an integer, convert it to a roman numeral. Input is guaranteed to be with ...

  8. LeetCode OJ:Integer to Roman(转换整数到罗马字符)

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

  9. 【LeetCode】12. Integer to Roman 整数转罗马数字

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:roman, 罗马数字,题解,leetcode, 力扣, ...

随机推荐

  1. Linux查看某个端口的连接数

    一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数 netstat -nat | grep -i "80" | wc -l 2)统计ht ...

  2. CentOS 特殊变量($0、$1、$2、 $?、 $# 、$@、 $*)

    名称 说明 $0 脚本名称 $1-9 脚本执行时的参数1到参数9 $? 脚本的返回值 $# 脚本执行时,输入的参数的个数 $@ 输入的参数的具体内容(将输入的参数作为一个多个对象,即是所有参数的一个列 ...

  3. C++类有继承时,析构函数必须为虚函数

    C++类有继承时,析构函数必须为虚函数.如果不是虚函数,则使用时可能存在内在泄漏的问题. 假设我们有这样一种继承关系: 如果我们以这种方式创建对象: SubClass* pObj = new SubC ...

  4. Python+Selenium学习--异常截图

    前言 Webdriver 提供错误截图函数get_screenshot_as_file(),可以帮助我们跟踪bug,在脚本无法继续执行时候, get_screenshot_as_file()函数将截取 ...

  5. protobuf shutdownprotobuflibrary的时候crash,释放的指针出错

    往往是多个子项目中有多次链接使用. 解决方法: 1. 使用静态库. 2. issure中有说2.6.1还未允许多次释放,建议使用3.4.x版本. 参考: https://github.com/prot ...

  6. Swift 从OC入门

    前言:断断续续学了蛮多天的Swift,感触还是蛮多的~~ 1.OC是以C语言为基础的语言,学习之前有C语言的基础,所以对于 `*` 这些指针还是比较容易理解的.问过其他程序员,对OC里面的 `*` 指 ...

  7. Quartz.Net进阶之三:SimpleTrigger详述

    以前都是将所有的内容放在一篇文章里,就会导致文章很长,对于学习的人来说,有时候这也是一个障碍.所以,以后我的写作习惯,我就会把我写的文章缩短,但是内容不会少,内容更集中.这样,学习起来也不会很累,很容 ...

  8. BZOJ1015或洛谷1197 [JSOI2008]星球大战

    BZOJ原题链接 洛谷原题链接 发现正着想毫无思路,所以我们可以考虑倒着思考,把摧毁变成建造. 这样很容易想到用并查集来维护连通块,问题也变的很简单了. 建原图,先遍历一遍所有边,若某条边的两端点未被 ...

  9. FT_ND_API.dll

    ePass1000ND https://blog.csdn.net/li34442779/article/details/44276989 https://www.cnblogs.com/lidabo ...

  10. Release file is expired, Updates for this repository will not be applied.(资源索引文件过期问题)

    将Debian下载源同步到本地之后,通过本地资源地址进行apt update操作时提示过期问题: E: Release file for http://localhost/security/dists ...