专栏首页程序猿杂货铺【LeetCode题解-012】Integer to Roman

【LeetCode题解-012】Integer to Roman

1题目

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

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:

Input: 3
Output: "III"

Example 2:

Input: 4
Output: "IV"

Example 3:

Input: 9
Output: "IX"

Example 4:

Input: 58
Output: "LVIII"
Explanation: L = 50, V = 5, III = 3.

Example 5:

Input: 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

2翻译

罗马数字包含以下七种字符: 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 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 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}

MMMM      4000
MMM       3000
MM        2000
M         1000

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

CM        900
DCCC      800
DCC       700
DC        600
D         500
CD        400
CCC       300
CC        200
C         100

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

XC        90
LXXX      80
LXX       70
LX        60
L         50
XL        40
XXX       30
XX        20
X         10

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

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。

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;
    }

本文分享自微信公众号 - 程序猿杂货铺(zhoudl_l),作者:zhoudl

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 为什么arrayList.removeAll(set)的速度远高于arrayList.removeAll(list)?

    我们知道,对于集合(Collection)都有一个抽象方法removeAll(Collection<?> c)!

    周三不加班
  • 【MySQL一】开发人心里都该有的那颗 B 树

    对该二叉树的节点进行查找发现深度为1的节点的查找次数为1,深度为2的查找次数为2,深度为n的节点的查找次数为n,因此其平均查找次数为(1+2+2+3+3+3) ...

    周三不加班
  • 一个关于国密 SM4 的故事

    我的名字叫 SM4,我还有三位兄长,分别是大哥 SM1, 二哥 SM2, 和三哥 SM3。说起我的名字,故事要回到2006 年的时候,我出生的时候并不是叫 SM...

    周三不加班
  • 如何在Ubuntu 14.04上使用PostgreSQL和Ruby on Rails应用程序

    Ruby on Rails使用sqlite3作为其默认数据库,在许多情况下效果很好,但可能不适合您的应用程序。如果您的应用程序需要客户端/服务器SQL数据库(如...

    温浪
  • 3ds Max 中的导航控件ViewCube入门介绍

    Zoctopus
  • 吞了1000瓶老干妈的南山头铁鹅,Python制作千图成像(附上源代码和应用程序)

    最近的瓜可谓真有意思,南山头铁鹅也默默吞下下了1000瓶老干妈。此时用这张1000张老干妈辣椒酱图片组成的企鹅来表达最适合不过了

    行哥玩Python
  • SparkStreaming+Kafka 实现统计基于缓存的实时uv

    董可伦
  • 《九》Swoole Redis 连接池的实现

    上篇文章 分享了 MySQL 连接池,这篇文章 咱们来分享下 Redis 连接池。

    新亮
  • 重启数据库的一场闹剧(r5笔记第68天)

    在几周前,某个测试环境在尝试impdp导入dump的时候报了错误,有个DBA立马做了kill session的操作,但是持续了5个小时,session状态还是K...

    jeanron100
  • Golang语言--映射

    Go编程提供另一个重要的数据类型是映射,唯一映射一个键到一个值。一个键要使用在以后检索值的对象。给定的键和值,可以在一个Map对象存储的值。值存储后,您可以使用...

    李海彬

扫码关注云+社区

领取腾讯云代金券