13. Roman to Integer

问题

Given a roman numeral, convert it to an integer.

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

例子

2017
MMXVIII

分析

  • 方法一:可以参考12. Integer to Roman映射表的思路,建立罗马数字到阿拉伯数字的映射表。映射表中的罗马数字的顺序从大到小排序。遍历并切割字符串,依次和映射表中的罗马数字匹配,把匹配结果累加即可。映射表如下:
vector> s2i{{"MMM", 3000}, {"MM", 2000}, {"M", 1000},
            {"CM", 900}, {"DCCC", 800}, {"DCC", 700}, {"DC", 600}, {"D", 500}, {"CD", 400}, {"CCC", 300}, {"CC", 200}, {"C", 100},
            {"XC", 90}, {"LXXX", 80}, {"LXX", 70}, {"LX", 60}, {"L", 50}, {"XL", 40}, {"XXX", 30}, {"XX", 20}, {"X", 10},
            {"IX", 9}, {"VIII", 8}, {"VII", 7}, {"VI", 6}, {"V", 5}, {"IV", 4}, {"III", 3}, {"II", 2}, {"I", 1}
        };
  • 方法二:映射表不需要那么大,只要保存M D C L X V I这七个基本罗马数字和阿拉伯数字的对应关系就可以了:
unordered_map s2i{{'M', 1000}, {'D', 500}, {'C', 100}, {'L', 50}, {'X', 10}, {'V', 5}, {'I', 1}};

然后逐字符遍历字符串,也不需要切割字符串。判断当前字符是不是比下一个字符要对应的阿拉伯数字要大,如果大,就加上当前字符对应的阿拉伯数字;否则减。

要点

  • 罗马数字最混淆不清的就是CM(900) XL(40) IV(4)这些数字,涉及到大位数字减去小位数字;
  • c++的字符串处理,不得不说,真的很烂。。。

时间复杂度

O(n),n为罗马数字长度。实际上这个数字很短,3999对应的罗马数字MMMCMXCIX才9位数字,所以时间复杂度几乎为O(1).

空间复杂度

O(1)

代码

方法一

class Solution {
public:
    int romanToInt(string s) {
        vector> s2i{{"MMM", 3000}, {"MM", 2000}, {"M", 1000},
            {"CM", 900}, {"DCCC", 800}, {"DCC", 700}, {"DC", 600}, {"D", 500}, {"CD", 400}, {"CCC", 300}, {"CC", 200}, {"C", 100},
            {"XC", 90}, {"LXXX", 80}, {"LXX", 70}, {"LX", 60}, {"L", 50}, {"XL", 40}, {"XXX", 30}, {"XX", 20}, {"X", 10},
            {"IX", 9}, {"VIII", 8}, {"VII", 7}, {"VI", 6}, {"V", 5}, {"IV", 4}, {"III", 3}, {"II", 2}, {"I", 1}
        };
        
        int res = 0;
        for (size_t i = 0; i < s.size();) {
            for (size_t j = 0; j < s2i.size(); j++) {
                if (i + s2i[j].first.size() > s.size()) continue;
                string roman = s.substr(i, s2i[j].first.size());
                if (roman == s2i[j].first) {
                    res += s2i[j].second;
                    i += s2i[j].first.size();
                    break;
                }
            }
        }
        return res;
    }
};

方法二

class Solution {
public:
    int romanToInt(string s) {
        unordered_map s2i{{'M', 1000}, {'D', 500}, {'C', 100}, {'L', 50}, {'X', 10}, {'V', 5}, {'I', 1}};
        int res = 0;
        for (int i = 0; i < s.length() - 1; i++) {
            if (s2i[s[i]] < s2i[s[i + 1]])
                res -= s2i[s[i]];
            else
                res += s2i[s[i]];
        }
        res += s2i[s.back()];
        return res;
    }
};

你可能感兴趣的:(13. Roman to Integer)