【LittleDuck_LeetCodeNote】13 - Roman to Integer

閱讀時間約 13 分鐘

A realistic, brightly colored interior home-style drawing in blue tones of a software engineer. - Leonardo.ai

Question and Hints

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
Symbol        Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, 2 is written as II in Roman numeral, just two ones added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
  • I can be placed before V (5) and X (10) to make 4 and 9.
  • X can be placed before L (50) and C (100) to make 40 and 90.
  • C can be placed before D (500) and M (1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.
Example 1:
Input: s = "III"
Output: 3
Explanation: III = 3.
Example 2:
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 3:
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
Constraints:
  • 1 <= s.length <= 15
  • s contains only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M').
  • It is guaranteed that s is a valid roman numeral in the range [1, 3999].

First Solution

💡 用switch-case從第一個字母開始找,
用對應的文字找出這一輪對應的的Index,記錄為nowIndex,
因為羅馬數字有將小字母擺在大字母左邊表示相減的特性,
所以檢查上一個字母(lastIndex)是否小於nowIndex,
如果是,就先相減,再做相加,
如果不是就直接加。
class Solution {
public int romanToInt(String s) {
char[] RomanNumber = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
int[] RomanValue = {1, 5, 10, 50, 100, 500, 1000};
int lastIndex = 0, nowIndex = 0, result = 0;

for(int i=0; i < s.length(); i++){
switch(s.charAt(i)){
case 'I':
nowIndex = 0;
break;
case 'V':
nowIndex = 1;
break;
case 'X':
nowIndex = 2;
break;
case 'L':
nowIndex = 3;
break;
case 'C':
nowIndex = 4;
break;
case 'D':
nowIndex = 5;
break;
case 'M':
nowIndex = 6;
break;
}
if(i == 0)
lastIndex = nowIndex;
if(lastIndex < nowIndex){
result -= RomanValue[lastIndex] * 2;
}
result += RomanValue[nowIndex];
lastIndex = nowIndex;
}

return result;
}
}
⏰ Runtime: 4 ms (95.38 %)
📦 Memory: 42.8 MB (57.74 %)

Upgrade Solution

more clear.
💡 First Solution邏輯大致上對了,但可以改得更精簡, 並且,順序反過來會更好找。
  • 不用2個陣列,而是直接在switch-case完成羅馬數字的參照轉換(透過number)
  • 因為不用陣列,所以不用Index,而是直接用字母代表的數字進行比較。
  • 「小字母擺在大字母左邊表示相減的特性」從數學角度來看,即當由右往左看時,下一個數字如果比較小,就要進行相減,比起原本相減2次更直觀。
  • JDK14更新了switch-case的寫法,改用 -> 取代 : ,且結尾不用再寫break。
class Solution {
public int romanToInt(String s) {
int answer = 0, number = 0, prev = 0;

for (int j = s.length()-1; j >= 0; j--) {
switch (s.charAt(j)) {
case 'M' -> number = 1000;
case 'D' -> number = 500;
case 'C' -> number = 100;
case 'L' -> number = 50;
case 'X' -> number = 10;
case 'V' -> number = 5;
case 'I' -> number = 1;
}
if (number < prev)
answer -= number;
else
answer += number;
prev = number;
}
return answer;
}
}
⏰ Runtime: 3 ms (100 %)
📦 Memory: 42.9 MB (57.74 %)

Bonus Solution

Use Hashtable to store Roman numbers.
💡 與First Solution的邏輯相同,差別在於用Hashtable替代兩個陣列,
結果來看明顯比較慢,
其實兩個陣列的搜尋方式就跟Hashtable的道理是一樣的,
只是把key跟value寫出來,
並且中間沒有Hash function轉換,
所以兩個陣列反而比較快,
但HashTable還是有安全性上的優點。
class Solution {
public int romanToInt(String s) {
Map<Character,Integer>map = new HashMap<>();
map.put('I',1);
map.put('V',5);
map.put('X',10);
map.put('L',50);
map.put('C',100);
map.put('D',500);
map.put('M',1000);

int value=0;
char prevVal = 'I';
for(int i=s.length()-1; i>=0; i--){
char nowVal = s.charAt(i);
if(map.get(nowVal) < map.get(prevVal))
value -= map.get(nowVal);
else
value += map.get(nowVal);
prevVal = nowVal;
}
return value;
}
}
⏰ Runtime: 7 ms (35.9 %)
📦 Memory: 42.6 MB (82.32 %)
為什麼會看到廣告
avatar-img
6會員
36內容數
以英文和日文歌的翻譯為主,並從「歌曲裡的故事」這個角度去翻譯。畢竟自己只有中文算好而已 :D
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Steven SHIH的沙龍 的其他內容
Palindrome Number : 判斷x是否為迴文 ( 左到右,右到左,內容皆相同 ) ,若符合回傳true,不符合則回傳false。
Two Sum : 在Array中找出相加後與Target相同的兩個數字,並將他們的index存在新的陣列。
Palindrome Number : 判斷x是否為迴文 ( 左到右,右到左,內容皆相同 ) ,若符合回傳true,不符合則回傳false。
Two Sum : 在Array中找出相加後與Target相同的兩個數字,並將他們的index存在新的陣列。
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
在這篇文章中,我們將深入剖析 LeetCode 題目 13. Roman to Integer 的解題方法。這是一道經典題目,要求我們將羅馬數字轉換為整數表示。通過學習這篇教學,你將掌握如何處理羅馬數字的規則和高效地實現轉換。
在這篇文章中,我們將探討 LeetCode 題目 12. Integer to Roman 的解題方法。這是一道經典的模擬題,要求我們將整數轉換為羅馬數字表示。通過這篇文章,你將學會如何高效地解決這道題,並理解羅馬數字的基本規則和轉換技巧。
Thumbnail
題目敘述 Integer to English Words 給定一個整數num 請轉換成對應的的英文數字表達(One, Two, Three, ... 那種數字表達式)
Thumbnail
題目敘述: Reverse Bits 給定一個32bit的整數,請逆序翻轉其二進位表達式,輸出翻轉過後的數字。 例如輸入是二進位1010111 逆序翻轉後是 1110101,對應的十進位數值是117 測試範例 Example 1: Input: n = 00000010100101000
Thumbnail
題目敘述 Combination Sum IV 給定一個輸入陣列nums,和目標值target,從nums裡面挑數字去湊出總和 = target,數字可以重複挑選。 請問有多少排列數可以湊出target? 註: 排列數的意思就是位置不同代表兩種不同的方法數。
※ 常用number型態的運算方法: 加、減、乘、除 求餘數(mod):% ※ JavaScript 內建的 Math 物件提供了許多number相關的方法和常數。以下是一些常見的內建 Math 功能: Math.PI:算出圓的面積。 Math.ceil:無條件進位 Math.floor
Thumbnail
今天想聊一組比較冷門的函式,ARABIC 跟 ROMAN 函式,它可以把羅馬數字轉跟阿拉伯數字互換,語法相當單純好學!
Thumbnail
題目敘述 題目會給我們一個輸入陣列tokens,裡面以逆序波蘭表達式的方式儲存各個token,請問最後計算完的值是多少? 例如: ["6", "2", "/"] 代表 6 / 2 =3 題目的原文敘述 測試範例 Example 1: Input: tokens = ["2","1"
Thumbnail
在Python中,數值運算非常直觀,你可以使用標準的數學運算符號進行基本的數值運算。以下是一些基本的數值運算: 進行計算時,按照「先乘除後加減」的規則,並優先計算小括號刮起來的運算式。 print('答案:' ,(1+1)*2) #​答案: 4 復合型態的運算子 指定運算子 = 若是結合算術
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
在這篇文章中,我們將深入剖析 LeetCode 題目 13. Roman to Integer 的解題方法。這是一道經典題目,要求我們將羅馬數字轉換為整數表示。通過學習這篇教學,你將掌握如何處理羅馬數字的規則和高效地實現轉換。
在這篇文章中,我們將探討 LeetCode 題目 12. Integer to Roman 的解題方法。這是一道經典的模擬題,要求我們將整數轉換為羅馬數字表示。通過這篇文章,你將學會如何高效地解決這道題,並理解羅馬數字的基本規則和轉換技巧。
Thumbnail
題目敘述 Integer to English Words 給定一個整數num 請轉換成對應的的英文數字表達(One, Two, Three, ... 那種數字表達式)
Thumbnail
題目敘述: Reverse Bits 給定一個32bit的整數,請逆序翻轉其二進位表達式,輸出翻轉過後的數字。 例如輸入是二進位1010111 逆序翻轉後是 1110101,對應的十進位數值是117 測試範例 Example 1: Input: n = 00000010100101000
Thumbnail
題目敘述 Combination Sum IV 給定一個輸入陣列nums,和目標值target,從nums裡面挑數字去湊出總和 = target,數字可以重複挑選。 請問有多少排列數可以湊出target? 註: 排列數的意思就是位置不同代表兩種不同的方法數。
※ 常用number型態的運算方法: 加、減、乘、除 求餘數(mod):% ※ JavaScript 內建的 Math 物件提供了許多number相關的方法和常數。以下是一些常見的內建 Math 功能: Math.PI:算出圓的面積。 Math.ceil:無條件進位 Math.floor
Thumbnail
今天想聊一組比較冷門的函式,ARABIC 跟 ROMAN 函式,它可以把羅馬數字轉跟阿拉伯數字互換,語法相當單純好學!
Thumbnail
題目敘述 題目會給我們一個輸入陣列tokens,裡面以逆序波蘭表達式的方式儲存各個token,請問最後計算完的值是多少? 例如: ["6", "2", "/"] 代表 6 / 2 =3 題目的原文敘述 測試範例 Example 1: Input: tokens = ["2","1"
Thumbnail
在Python中,數值運算非常直觀,你可以使用標準的數學運算符號進行基本的數值運算。以下是一些基本的數值運算: 進行計算時,按照「先乘除後加減」的規則,並優先計算小括號刮起來的運算式。 print('答案:' ,(1+1)*2) #​答案: 4 復合型態的運算子 指定運算子 = 若是結合算術