题目:

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

官方难度:

Medium

翻译:

给定一个范围在1-3999内的整数,将其转化成罗马数字。

补充资料:

罗马数字规则:

  • 需要用到的罗马数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。罗马数字中没有0。
  • 一个罗马数字最多重复3次。
  • 右加左减:
    在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。
    在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
  • 左减的数字有限制,仅限于I、X、C,且放在大数的左边只能用一个。
    (*) V 和 X 左边的小数字只能用I。
    (*) L 和 C 左边的小数字只能用X。
    (*) D 和 M 左 边的小数字只能用C。

方法一:

  1. 利用一个二维数组,可以很清晰直观地根据维度来记录罗马字符。
  2. 获取最高位数,根据当前所在位置,对应二维数组的维度。
  3. 获取当前数字,4和9需要特殊处理。
  4. 判断当前数字是否大于等于5,将5对应的罗马字符加入结果字符串。
  5. 计算当前数字除以5的余数,累加1对应的罗马字符。
  6. 入参检查。

方法一的解题代码:

         // 使用二维数组,存储罗马字符集
private static String method(int num) {
StringBuffer result = new StringBuffer();
// 罗马字符集
char[][] roman = new char[][] { { 'I', 'V' }, { 'X', 'L' }, { 'C', 'D' }, { 'M' } };
// 确定最高位数
int length = String.valueOf(num).length();
while (length-- > 0) {
// 罗马数字从左往右是最高位的
int current = (int) ((num / Math.pow(10, length)) % 10);
// 4、9特殊处理
if (current == 4) {
result.append("" + roman[length][0] + roman[length][1]);
} else if (current == 9) {
result.append("" + roman[length][0] + roman[length + 1][0]);
} else {
// 大于等于5处理
if (current / 5 == 1) {
result.append(roman[length][1]);
}
// 加1
for (int i = 0; i < current % 5; i++) {
result.append(roman[length][0]);
}
}
}
return result.toString();
}

method

方法二:

  1. 方法一中使用到了二维数组,可以直观地得到罗马字符,但是二维数组的存储效率是很低的。在Java中,没有二维数组的原生态概念,我们所谓的“二维数组”,其本质是数组的数组,这和C里面不同。Java中使用二维数组,无论是在存储空间还是读取速度方面,都有比较大的劣势,在有等效替代的方法情况下,尽量不要使用二维数组。
  2. 题中的二维数组是2*4的,对于m*n的二维数组,可以使用一维数组代替,下标索引的计算,可以参考m进制的加法原理。

方法二的解题代码:

     public static String intToRoman(int num) {
if (num > 3999 || num < 1) {
throw new IllegalArgumentException("Input error");
}
StringBuffer result = new StringBuffer();
// 确定最高位数
int length = String.valueOf(num).length();
while (length-- > 0) {
// 罗马数字从左往右是最高位的
int current = (int) ((num / Math.pow(10, length)) % 10);
// 4、9特殊处理
if (current == 4) {
result.append("" + romanDict(length, 0) + romanDict(length, 1));
} else if (current == 9) {
result.append("" + romanDict(length, 0) + romanDict(length + 1, 0));
} else {
// 大于等于5处理
if (current / 5 == 1) {
result.append(romanDict(length, 1));
}
// 加1
for (int i = 0; i < current % 5; i++) {
result.append(romanDict(length, 0));
}
}
}
return result.toString();
} // 罗马数字字典
private static char romanDict(int x, int y) {
char[] roman = new char[] { 'I', 'V', 'X', 'L', 'C', 'D', 'M' };
return roman[x * 2 + y];
}

intToRoman

相关链接:

https://leetcode.com/problems/integer-to-roman/

https://github.com/Gerrard-Feng/LeetCode/blob/master/LeetCode/src/com/gerrard/algorithm/medium/Q012.java

PS:如有不正确或提高效率的方法,欢迎留言,谢谢!

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

  1. lintcode :Integer to Roman 整数转罗马数字

    题目 整数转罗马数字 给定一个整数,将其转换成罗马数字. 返回的结果要求在1-3999的范围内. 样例 4 -> IV 12 -> XII 21 -> XXI 99 -> XC ...

  2. leetcode:Integer to Roman(整数转化为罗马数字)

    Question: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the rang ...

  3. 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 ...

  4. 58. 分析、测试与总结:罗马数字和阿拉伯数字的转换[roman to integer and integer to roman in c++]

    [本文链接] http://www.cnblogs.com/hellogiser/p/roman-to-integer-and-integer-to-roman.html [题目] 给出一个罗马数字, ...

  5. No.012 Integer to Roman

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

  6. leetcode:Roman to Integer and Integer to Roman

    2015-06-03 罗马数字以前接触过I到VIII比较多,直到遇见这个题目才知道更详细.阿拉伯数字和罗马数字之间的转换最重的是了解罗马数字的规则. 罗马数字规则:(总结) 1, 罗马数字共有7个,即 ...

  7. LeetCode--No.012 Integer to Roman

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

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

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

  9. 【LeetCode】Roman to Integer & Integer to Roman

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

随机推荐

  1. SQL语句调优 - 索引上的数据检索方法

    如果一张表上没有聚集索引,数据将会随机的顺序存放在表里.以dbo.SalesOrderDetail_TEST为例子.它的上面没有聚集索引,只有一个在SalesOrderID上的非聚集索引.所以表格的每 ...

  2. [转]BloomFilter——大规模数据处理利器

    Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合. 一. 实例 为了说明Bl ...

  3. Oracle 11g RAC客户端使用SCAN IP无法连接问题

    Oracle 版本:11.2.0.1.0 客户端:Windows Server 2003/PLSQL Developer Oracle服务器端的ip设置如下: ##公网ip 192.168.135.2 ...

  4. apache服务器配置Net的实践

    前置: 在xp系统中,打补丁之类或啥子操作引起或多或少的问题,最终导致iis不能使用: 不想装系统...忍着... 最近突发事件导致,需要摸一下apache服务器处理,好吧,那就搜索下吧..... 目 ...

  5. 控制反转(Ioc)和依赖注入(DI)

    控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...

  6. Form personization(Form 个性化)报无权限

    总部的同事利用form personization对工单的一些Form做了个性化,发现可能设的有问题,造成用户无法关工单.想要看一下她是怎么设的,可报没权限.经过研究发现,把个人Profile 的 U ...

  7. JavaScript高级之词法作用域和作用域链

    主要内容: 分析JavaScript的词法作用域的含义 解析变量的作用域链 变量名提升时什么 一.关于块级作用域         说到JavaScript的变量作用域,与咱们平时使用的类C语言不同. ...

  8. 【转】基于CXF Java 搭建Web Service (Restful Web Service与基于SOAP的Web Service混合方案)

    转载:http://www.cnblogs.com/windwithlife/archive/2013/03/03/2942157.html 一,选择一个合适的,Web开发环境: 我选择的是Eclip ...

  9. oracle监听程序无法启动(TNS-12560: TNS: 协议适配器错误,TNS-00530: 协议适配器错误)

    问题描述1:   C:\Users\Administrator>lsnrctl start LSNRCTL for 64-bit Windows: Version 11.2.0.1.0 - Pr ...

  10. [Git] Git 常用技巧

    版本对比 1. 对比两个 COMMIT git diff <commit> <commit> 2. 对比 COMMIT 和父 COMMIT git diff <commi ...