哈希表题目:罗马数字转整数

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:罗马数字转整数

出处:13. 罗马数字转整数

难度

3 级

题目描述

要求

罗马数字包含以下七种字符: I \texttt{I} I V \texttt{V} V X \texttt{X} X L \texttt{L} L C \texttt{C} C D \texttt{D} D M \texttt{M} M

字符 数值
I \texttt{I} I 1 \texttt{1} 1
V \texttt{V} V 5 \texttt{5} 5
X \texttt{X} X 10 \texttt{10} 10
L \texttt{L} L 50 \texttt{50} 50
C \texttt{C} C 100 \texttt{100} 100
D \texttt{D} D 500 \texttt{500} 500
M \texttt{M} M 1000 \texttt{1000} 1000

例如,罗马数字 2 \texttt{2} 2 写做 II \texttt{II} II,即为两个 1 \texttt{1} 1 相加。 12 \texttt{12} 12 写做 XII \texttt{XII} XII,即为 X   +   II \texttt{X + II} X + II 27 \texttt{27} 27 写做 XXVII \texttt{XXVII} XXVII,即为 XX   +   V   +   II \texttt{XX + V + II} XX + V + II

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 \texttt{4} 4 不写做 IIII \texttt{IIII} IIII,而是 IV \texttt{IV} IV,即数字 1 \texttt{1} 1 在数字 5 \texttt{5} 5 的左边,所表示的数等于 5 \texttt{5} 5 1 \texttt{1} 1 得到的数值 4 \texttt{4} 4。同样地,数字 9 \texttt{9} 9 表示为 IX \texttt{IX} IX。这个特殊的规则只适用于以下六种情况:

  • I \texttt{I} I 可以放在 V \texttt{V} V 5 \texttt{5} 5)和 X \texttt{X} X 10 \texttt{10} 10)的左边,来表示 4 \texttt{4} 4 9 \texttt{9} 9
  • X \texttt{X} X 可以放在 L \texttt{L} L 50 \texttt{50} 50)和 C \texttt{C} C 100 \texttt{100} 100)的左边,来表示 40 \texttt{40} 40 90 \texttt{90} 90
  • C \texttt{C} C 可以放在 D \texttt{D} D 500 \texttt{500} 500)和 M \texttt{M} M 1000 \texttt{1000} 1000)的左边,来表示 400 \texttt{400} 400 900 \texttt{900} 900

给你一个罗马数字,将其转换成整数。

示例

示例 1:

输入: s   =   "III" \texttt{s = "III"} s = "III"
输出: 3 \texttt{3} 3

示例 2:

输入: s   =   "IV" \texttt{s = "IV"} s = "IV"
输出: 4 \texttt{4} 4

示例 3:

输入: s   =   "IX" \texttt{s = "IX"} s = "IX"
输出: 9 \texttt{9} 9

示例 4:

输入: s   =   "LVIII" \texttt{s = "LVIII"} s = "LVIII"
输出: 58 \texttt{58} 58
解释: L   =   50 \texttt{L = 50} L = 50 V   =   5 \texttt{V = 5} V = 5 III   =   3 \texttt{III = 3} III = 3

示例 5:

输入: s   =   "MCMXCIV" \texttt{s = "MCMXCIV"} s = "MCMXCIV"
输出: 1994 \texttt{1994} 1994
解释: M   =   1000 \texttt{M = 1000} M = 1000 CM   =   900 \texttt{CM = 900} CM = 900 XC   =   90 \texttt{XC = 90} XC = 90 IV   =   4 \texttt{IV = 4} IV = 4

数据范围

  • 1 ≤ s.length ≤ 15 \texttt{1} \le \texttt{s.length} \le \texttt{15} 1s.length15
  • s \texttt{s} s 仅含字符 (‘I’,   ‘V’,   ‘X’,   ‘L’,   ‘C’,   ‘D’,   ‘M’) \texttt{(`I', `V', `X', `L', `C', `D', `M')} (‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, ‘M’)
  • 题目数据保证 s \texttt{s} s 是一个有效的罗马数字,表示在范围 [1,   3999] \texttt{[1, 3999]} [1, 3999] 内的一个整数

解法

思路和算法

将罗马数字转换成整数,只要将罗马数字中的每个字符转换成对应的数值,确定数值的正负性然后求和即可。

对于罗马数字中的每个字符,根据对应关系即可得到该字符对应的数值。只有当一个字符对应的数值小于后面一个字符对应的数值时,当前字符对应的数值才是负数,其余情况下当前字符对应的数值都是正数。

转换方法是:从左到右依次遍历罗马数字中的每个字符,对于每个字符进行如下操作。

  1. 得到当前字符对应的数值;

  2. 确定当前字符对应的数值的符号,如果当前字符是最后一个字符或者当前字符对应的数值大于或等于后面一个字符对应的数值,则当前字符对应的数值是正数,否则当前字符对应的数值是负数;

  3. 将当前字符对应的数值加到结果中。

代码

class Solution {
    static final Map<Character, Integer> SYMBOL_VALUE_MAP = new HashMap<Character, Integer>() {{
        put('I', 1);
        put('V', 5);
        put('X', 10);
        put('L', 50);
        put('C', 100);
        put('D', 500);
        put('M', 1000);
    }};

    public int romanToInt(String s) {
        int num = 0;
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char symbol = s.charAt(i);
            int value = SYMBOL_VALUE_MAP.get(symbol);
            if (i == length - 1 || value >= SYMBOL_VALUE_MAP.get(s.charAt(i + 1))) {
                num += value;
            } else {
                num -= value;
            }
        }
        return num;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 s s s 的长度。需要遍历罗马数字中的每个字符,对于每个字符转换成整数值的时间都是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( 1 ) O(1) O(1)。由于符号的数量固定,因此存储对应关系使用的空间固定。

你可能感兴趣的:(数据结构和算法,#,哈希表,哈希表)