LeetCode 12. Integer to Roman 解题报告

LeetCode 12. Integer to Roman 解题报告

题目描述

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.


示例

“19”
return “XIX”


限制条件

没有明确给出.


解题思路

我的思路:

之前有一道题是LeetCode 13. Roman to Integer里面有讲到罗马数字的规则,下面我再贴出来一下。
1.基本字母及其代表的数值
I = 1,V = 5,X = 10,L = 50,C = 100,D = 500,M = 1000

2.记数方式
(1)相同的数字连写,所表示的数等于这些数字相加得到的数,如: Ⅲ = 3;
(2)小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数, 如:Ⅷ = 8;Ⅻ = 12;
(3)小的数字,(限于Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如:Ⅳ = 4;Ⅸ = 9;

知道了上述规则之后,我的想法是对整数不断做减法,因为罗马数字其实就是各个基数的简单组合,比如600 = 500 + 100 = DC,所以从最大的基数开始,如果当前的整数比基数大,那就意味着这个整数的罗马数字表示中包含这个基数对应的字母,因此把该字母添加到结果字符串中,直到整数减至0。

然而这里出现了一个问题,就是罗马数字中表示4,9,40,90,400,900是通过上述规则的第三条表示的,如果直接用减法会导致出现4个连续相同的字母,这是不对的,比如4,用减法得到的结果为IIII。由于特殊的数只有这6个,所以干脆把这6个数也当作基数。假如我们遇到的整数为4,就直接从整数中减去4,并且添加“IV”到结果字符串中,其它5个特殊的数字同样操作。如此我们就能得到正确的结果。

参考思路:

大牛们的思路比我更强势,他们利用了题目里整数不超过3999这一条件,把个位,十位,百位,千位一共34种罗马数字的组合存储到数组中,然后依次取整数的千位,百位,十位,个位上的数字并查数组获取对应的字母,添加到结果字符串中,如此虽然耗费了空间,但是时间上会更快一些。


代码

我的代码

class Solution {
public:
    string intToRoman(int num) {
        vector<pair<string, int>> baseNumber {
            {"I",    1}, {"IV",   4}, {"V",   5}, {"IX",   9},
            {"X",   10}, {"XL",  40}, {"L",  50}, {"XC",  90},
            {"C",  100}, {"CD", 400}, {"D", 500}, {"CM", 900},
            {"M", 1000}
        };

        int i = 12;
        string roman;

        while (num > 0) {
            if (num >= baseNumber[i].second) {
                roman += baseNumber[i].first;
                num -= baseNumber[i].second;
            } else {
                i--;
            }
        }

        return roman;
    }
};

参考代码:

class Solution {
public:
    string intToRoman(int num) {
        char *rLetter[4][10] = {
            {"", "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 roman;

        roman += rLetter[3][num / 1000 % 10];
        roman += rLetter[2][num / 100 % 10];
        roman += rLetter[1][num / 10 % 10];
        roman += rLetter[0][num % 10];

        return roman;
    }
};

总结

这道题难度一般,关键是得想到要把特殊的数字跟对应的罗马字母存储起来,当然题目给出了整数范围,所以可以更进一步直接把所有可能的情况都存储起来,想到这一点,这道题就再也没有难度了。
填好今天的坑,明天继续,再忙也坚持每天填一个坑,坚持!加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值