今天挑戰的題目是 Integer to Roman,也就是把一個整數轉成羅馬數字。
乍看之下會覺得很麻煩,因為羅馬數字有些特別的規則,像是「4 不會寫成 IIII,而是 IV」、「9 要寫成 IX」之類的。但其實抓到規律後,做法就蠻直觀的。
題目核心
羅馬數字的組成方式:
正常情況下就是一直加同樣的字母,例如 3 = III, 30 = XXX
但遇到「4 或 9」時,要用減法表示,像 4 = IV, 9 = IX, 40 = XL, 900 = CM。
所以解法就是 準備一張對照表,把所有特殊情況先放進去,再一路從大到小去拼。
解題思路
先準備一個「數字 → 羅馬數字」的對照表,從大到小排好:
1000 → M
900 → CM
500 → D
400 → CD
100 → C
90 → XC
50 → L
40 → XL
10 → X
9 → IX
5 → V
4 → IV
1 → I
用迴圈一直檢查,如果 num >= value[i],就扣掉並把對應的羅馬字母加上去。
重複到 num = 0 為止。
Java程式碼
class Solution {
public String intToRoman(int num) {
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romans = {"M", "CM","D", "CD","C", "XC","L", "XL","X", "IX","V", "IV","I"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
while (num >= values[i]) {
num -= values[i];
sb.append(romans[i]);
}
}
return sb.toString();
}
}
測試範例
3749 → "MMMDCCXLIX"
58 → "LVIII"
1994 → "MCMXCIV"
心得
這題其實很適合練習「模版思維」。
一開始可能會想「要一直 if 判斷嗎?」但把特殊情況統一放進表格後,程式就變得非常乾淨。
而且這種題型跟「貪心法」很像:每次都挑目前能用的最大值,直到用完為止。
做完這題我覺得最重要的收穫是 —— 先整理規則,再寫程式會快很多。