2021.05.14 羅馬數字轉整數


題目來源:力扣(LeetCode

鏈接:https://leetcode-cn.com/problems/roman-to-integer/

難度:簡單

羅馬數字包含以下七種字符: IVXLCDM

字符          數值
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 到 3999 的范圍內。

示例 1:

輸入: "III"
輸出: 3

示例 2:

輸入: "IV"
輸出: 4

示例 3:

輸入: "IX"
輸出: 9

示例 4:

輸入: "LVIII"
輸出: 58
解釋: L = 50, V= 5, III = 3.

示例 5:

輸入: "MCMXCIV"
輸出: 1994
解釋: M = 1000, CM = 900, XC = 90, IV = 4.

提示:

  • 1 <= s.length <= 15
  • s 僅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M')
  • 題目數據保證 s 是一個有效的羅馬數字,且表示整數在范圍 [1, 3999]
  • 題目所給測試用例皆符合羅馬數字書寫規則,不會出現跨位等情況。
  • IL IM 這樣的例子並不符合題目要求,49 應該寫作 XLIX,999 應該寫作 CMXCIX
  • 關於羅馬數字的詳盡書寫規則,可以參考 羅馬數字 - Mathematics

提交記錄

這個題我沒發現有什么奇特的解法,基本就是根據題目描述,然后用代碼實現。首先創建了一個字典map,存放映射關系,變量定義成靜態變量的好處是,Solution類在實例化的時候,該部分代碼就會被初始化,不會增加系統執行方法時的性能,會更快。

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

    public int romanToInt(String s) {
        char[] chars = s.toCharArray();
        int sum = 0;
        for (int i = 0; i < chars.length; i++) {
            if (i >= 1 && chars[i - 1] == 'I' && (chars[i] == 'V' || chars[i] == 'X')) {
                sum += charIntMap.get(chars[i]) - 2;
            } else if (i >= 1 && chars[i - 1] == 'X' && (chars[i] == 'L' || chars[i] == 'C')) {
                sum += charIntMap.get(chars[i]) - 20;
            } else if (i >= 1 && chars[i - 1] == 'C' && (chars[i] == 'D' || chars[i] == 'M')) {
                sum += charIntMap.get(chars[i]) - 200;
            } else  {
                sum += charIntMap.get(chars[i]);
            }
        }
        return sum;
    }
}

性能也還不錯,執行用時超過了70%的提交記錄:

內存方面更是優秀,超過了96%的提交記錄

但是如果把map放進方法內部,性能就差太遠了。經過實測,確實如果直接把字典初始化這塊放到方法內部,不論是執行用時,還是內存消耗都會增加(最新的提交記錄是我們把map放到方法內部的結果):

這也說明,常量定義成靜態的,會讓我們的系統性能更好,效率更高。

總結

學習算法真正的意義是讓我們可以開發出性能更好的、效率更高的系統,當你慢慢知道了一行無用或者不合理的代碼,甚至多創建一個變量都會影響系統性能的時候,你才能在寫每一行代碼的時候更謹慎,慢慢積累,你才能寫出更優質的代碼。更多時候,你不夠優秀,並非是你不不上進、不努力,而是你沒看到更優秀的人……當然,你也可以當一個咸魚,但有機會的時候,也要記得翻個身哦,畢竟兩面曬才好吃


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM