12. Integer to Roman
MediumDescription
給定一個整數
num(1 <= num <= 3999),將其轉換為羅馬數字字串。
Example:
Input: num = 1994 Output: “MCMXCIV” (M=1000, CM=900, XC=90, IV=4)
Intuition#
核心思路:貪心法——從最大面額開始,盡量用大的符號表示,包含六個減法組合(CM、CD、XC、XL、IX、IV)。
- 羅馬數字有 13 種基本表示(7 個標準 + 6 個減法組合)
- 從大到小排列,每次取最大的可用符號,直到 num 為 0
- 這是典型的貪心策略
Approaches#
⭐1: 貪心查表#
- 概念: 建立值-符號對照表(從大到小),每次盡量多用最大符號
- 時間複雜度:
O(1)- num 最大 3999,迴圈次數有上界(約 15 次) - 空間複雜度:
O(1)- 結果字串長度有上界
class Solution {
fun intToRoman(num: Int): String {
val values = intArrayOf(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
val symbols = arrayOf("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I")
val sb = StringBuilder()
var n = num
for (i in values.indices) {
while (n >= values[i]) {
sb.append(symbols[i])
n -= values[i]
}
}
return sb.toString()
}
}2: 硬編碼各位數#
- 概念: 將千位、百位、十位、個位分別對應的羅馬數字列舉出來,直接查表
- 時間複雜度:
O(1) - 空間複雜度:
O(1)
class Solution {
fun intToRoman(num: Int): String {
val thousands = arrayOf("", "M", "MM", "MMM")
val hundreds = arrayOf("", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM")
val tens = arrayOf("", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC")
val ones = arrayOf("", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX")
return thousands[num / 1000] + hundreds[num % 1000 / 100] +
tens[num % 100 / 10] + ones[num % 10]
}
}🔑 Takeaways#
- Pattern: 貪心選擇最大面額——與找零錢問題類似
- 關鍵技巧: 把 6 個減法組合(CM, CD, XC, XL, IX, IV)也放入查表中,就不需要特殊處理減法規則