【LeetCode题解-012】Integer to Roman

2019-09-03 10:16:12 浏览数 (1)

1题目

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

代码语言:javascript复制
Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X II. The number twenty seven is written as XXVII, which is XX V II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

  • I can be placed before V (5) and X (10) to make 4 and 9.
  • X can be placed before L (50) and C (100) to make 40 and 90.
  • C can be placed before D (500) and M (1000) to make 400 and 900.

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

Example 1:

代码语言:javascript复制
Input: 3
Output: "III"

Example 2:

代码语言:javascript复制
Input: 4
Output: "IV"

Example 3:

代码语言:javascript复制
Input: 9
Output: "IX"

Example 4:

代码语言:javascript复制
Input: 58
Output: "LVIII"
Explanation: L = 50, V = 5, III = 3.

Example 5:

代码语言:javascript复制
Input: 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

2翻译

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

代码语言:javascript复制
字符          数值
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 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 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分析

首先我们要熟悉罗马数的表达方式。M是1000,D是500,C是100,L是50,X是10,V是5,I是1。验证字符串是否是罗马数,我们先看一下有效的罗马数是什么样的,假设该数字小于5000,从千位到个位依次拆解。千位的表达方式 M{0,4}

代码语言:javascript复制
MMMM      4000
MMM       3000
MM        2000
M         1000

百位的表达方式 (CM|CD|D?C{0,3})

代码语言:javascript复制
CM        900
DCCC      800
DCC       700
DC        600
D         500
CD        400
CCC       300
CC        200
C         100

十位的表达方式 (XC|XL|L?X{0,3})

代码语言:javascript复制
XC        90
LXXX      80
LXX       70
LX        60
L         50
XL        40
XXX       30
XX        20
X         10

个位的表达方式 (IX|IV|V?I{0,3})

代码语言:javascript复制
IX        9
VIII      8
VII       7
VI        6
V         5
IV        4
III       3
II        2
I         1

所以我们正则表达式的就是将这四个部分顺序组合在一起就行了。

注意

  • 罗马数字没有0
  • 正则表达式以^开头,以$结尾

4解法 贪心法

复杂度

时间 O(N) 空间 O(1)

思路

因为罗马数字都是由最大化的表示,比如10会表示成X而不是VV,所以我们可以从最大可能的表示向小的依次尝试。因为提示1-3999,所有的可能性不多,我们可以直接打表来帮助我们选择表示方法。在一个数量级中有四种可能的表示方法,以1-9为例,1-3是由I表示出来的,4是IV,5是V,6-8是V和若干个I,9是IX。

代码语言:javascript复制
public String intToRoman(int num) {
        String str = "";
        String[] strings = {"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
        int[] values = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
        for (int i = 12 ; num !=0 ; i --) {
            while (num >= values[i]) {
                num -= values[i];
                str  = strings[i];
            }
        }
        return str;
    }

0 人点赞