題目
羅馬數(shù)字轉(zhuǎn)整數(shù)
https://leetcode-cn.com/problems/roman-to-integer/
公眾號 《java編程手記》記錄JAVA學(xué)習(xí)日常欺劳,分享學(xué)習(xí)路上點點滴滴,從入門到放棄铅鲤,歡迎關(guān)注
描述
難度:簡單
羅馬數(shù)字包含以下七種字符: I划提, V, X邢享, L鹏往,C,D 和 M骇塘。
字符 數(shù)值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如伊履, 羅馬數(shù)字 2
寫做 II
,即為兩個并列的 1
款违。12
寫做 XII
唐瀑,即為 X + II
。 27
寫做 XXVII
, 即為 XX + V + II
插爹。
通常情況下哄辣,羅馬數(shù)字中小的數(shù)字在大的數(shù)字的右邊。但也存在特例赠尾,例如 4
不寫做 IIII
力穗,而是 IV
。數(shù)字 1
在數(shù)字 5
的左邊气嫁,所表示的數(shù)等于大數(shù) 5
減小數(shù) 1
得到的數(shù)值 4
当窗。同樣地,數(shù)字 9
表示為 IX
杉编。這個特殊的規(guī)則只適用于以下六
種情況:
-
I
可以放在V (5)
和X (10)
的左邊超全,來表示4
和9
咆霜。 -
X
可以放在L (50)
和C (100)
的左邊,來表示40
和90
嘶朱。 -
C
可以放在D (500)
和M (1000)
的左邊蛾坯,來表示400
和900
。 - 給定一個羅馬數(shù)字疏遏,將其轉(zhuǎn)換成整數(shù)脉课。輸入確保在
1
到3999
的范圍內(nèi)。
示例 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')
題目數(shù)據(jù)保證 s 是一個有效的羅馬數(shù)字财异,且表示整數(shù)在范圍 [1, 3999] 內(nèi)
題目所給測試用例皆符合羅馬數(shù)字書寫規(guī)則倘零,不會出現(xiàn)跨位等情況。
IL 和 IM 這樣的例子并不符合題目要求戳寸,49 應(yīng)該寫作 XLIX呈驶,999 應(yīng)該寫作 CMXCIX 。
關(guān)于羅馬數(shù)字的詳盡書寫規(guī)則疫鹊,可以參考 羅馬數(shù)字 - Mathematics 袖瞻。
Solution
正常解法
解題思路
整理出所有的對應(yīng)關(guān)系
昨天做的整數(shù)到羅馬,今天兩級反轉(zhuǎn)拆吆,羅馬到整數(shù)聋迎,思路本質(zhì)是一樣的,找對應(yīng)映射轉(zhuǎn)換關(guān)系枣耀,特殊點就在于 IV IX XL XC
這類表示先減后加
的邏輯
image-20210420221849374
- 首先找到對應(yīng)羅馬字符的
整數(shù)
及其對應(yīng)的前一個
羅馬字符對應(yīng)的整數(shù)
霉晕,注意這里是羅馬字符對應(yīng)轉(zhuǎn)換的整數(shù)
- 這里可以用
getValue
抽象獲取羅馬字符對應(yīng)的整數(shù) - 我們的整體思路是在
i
的迭代遍歷中計算i-1
的數(shù)據(jù),然后在最后加上i
的值- 判斷
前一個整數(shù)
與當(dāng)前整數(shù)
的值捞奕,- 如果
前一個整數(shù)
小于當(dāng)前整數(shù)
的值牺堰,說明是特殊情況,需要先減去對應(yīng)的前一個的數(shù)值 - 其他情況則正常加上
前一個整數(shù)
的值
- 如果
- 在最后加上
I
的值
- 判斷
CODE
class Solution {
public int romanToInt(String s) {
int len = s.length();
int sum = 0;
int preNum = getValue(s.charAt(0));
for(int i = 1 ; i<len ; i++){
char c = s.charAt(i);
int num= getValue(c);
//在i的迭代計算i-1的值
if(preNum < num){
//特殊情況缝彬,先減去值,比如針對 IV = 4 萌焰,這里就是 -1(I)
sum -= preNum;
}else{
//正常加上值 針對 IV = 4 哺眯,這里就是 +5(V)
sum += preNum;
}
// 將當(dāng)前i賦值給i+1谷浅,在下一個迭代中計算
preNum = num;
}
//在最后加上I的值
sum +=preNum;
return sum;
}
private int getValue(char ch) {
switch(ch) {
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
default: return 0;
}
}
}
復(fù)雜度
- 時間復(fù)雜度
O(N)
, N為羅馬字符的長度
結(jié)果
- 執(zhí)行用時:
4
ms, 在所有Java
提交中擊敗了100.00
%的用戶 - 內(nèi)存消耗:
38.5
MB, 在所有Java
提交中擊敗了72.23
%的用戶
LeetCode名句
這題屬于簡單嗎?奶卓?一疯?