Intuition
List every Roman value (including the subtractive forms like 900=CM and 4=IV) from largest to smallest. Repeatedly append the largest symbol that still fits and subtract its value, until the number reaches zero.
Explanation
Idea
Roman numerals are written largest-to-smallest. If we include the six subtractive forms (CM, CD, XC, XL, IX, IV) directly in our value table, the whole conversion becomes a clean greedy loop: always take the biggest symbol that doesn't overshoot.
Algorithm
- Build a descending list of
(value, symbol)pairs including the subtractive forms. - For each pair, while
num >= value, appendsymboland subtractvalue. - Return the accumulated string.
Worked example: 1994
| step | num | fits | append |
|---|---|---|---|
| 1 | 1994 | 1000 (M) | M → 994 |
| 2 | 994 | 900 (CM) | CM → 94 |
| 3 | 94 | 90 (XC) | XC → 4 |
| 4 | 4 | 4 (IV) | IV → 0 |
Result: "MCMXCIV".
Complexity
- Time: O(1) — at most a constant number of symbols (num ≤ 3999).
- Space: O(1).
Implementation
class Solution {
public String intToRoman(int num) {
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] symbols = {"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]) {
sb.append(symbols[i]);
num -= values[i];
}
}
return sb.toString();
}
}