LeetCode-12-整数转罗马数字

题目

来源:LeetCode.

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字2 写做II,即为两个并列的112 写做 XII ,即为X + II27 写做 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:

输入: num = 3
输出: "III"

示例 2:

输入: num = 4
输出: "IV"

示例 3:

输入: num = 9
输出: "IX"

示例 4:

输入: num = 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.

示例 5:

输入: num = 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= num <= 3999

接下来看一下解题思路:

思路:

    刚开始看到这道题,想的是用 if - else 写,结果流下了痛苦的眼泪 😮
    后来才想到根据罗马数字出现的可能保存到数组然后遍历转换;
    首先,罗马数字由 7 个不同的单字母符号组成,而且还有 6 个特殊情况:
{ M     → 1000 C M → 900 D      → 500 C D   → 400 C      → 100 X C   → 90 L       → 50 X L    → 40 X       → 10 I X     → 9 V       → 5 I V     → 4 I        → 1 \begin{cases} M \ \ \ \rightarrow 1000\\ CM \rightarrow 900\\ D \ \ \ \ \rightarrow 500\\ CD \ \rightarrow 400\\ C \ \ \ \ \rightarrow 100\\ XC \ \rightarrow 90\\ L \ \ \ \ \ \rightarrow 50\\ XL \ \ \rightarrow 40\\ X \ \ \ \ \ \rightarrow 10\\ IX \ \ \ \rightarrow 9\\ V \ \ \ \ \ \rightarrow 5\\ IV \ \ \ \rightarrow 4\\ I \ \ \ \ \ \ \rightarrow 1\\ \end{cases} M   1000CM900D    500CD 400C    100XC 90L     50XL  40X     10IX   9V     5IV   4I      1
    1、对于转换,需要根据当前数字选择尽可能大的罗马数组,然后减去该值;
    然后重复步骤 1 ,直到这个数字为 0 ;
    需要给两个数组保存罗马字符和对应的数字;
    并且从大到小存储,包装字符和数字一一对应;

public static String intToRoman(int num) {
    // 1 <= num <= 3999
    if (num < 1 || num > 3999) {
        throw new IllegalArgumentException();
    }
    
    int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
    String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};

    StringBuffer result = new StringBuffer();

    for (int i = 0; i < values.length; ++i) {
        while (num >= values[i]) {
            num -= values[i];
            result.append(symbols[i]);
        }
        if (num == 0) {
            break;
        }
    }
    return result.toString();
}
总结

    时间复杂度 O(1),由于 v a l u e s values values S y m b o l s Symbols Symbols 长度是固定的,且这 13 字符中的每个字符的出现次数均不会超过 3,因此循环次数有一个确定的上限。对于本题给出的数据范围,循环次数不会超过 15 次;
    空间复杂度 O(1);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值