Python Program to Convert Integer to Roman Numerals
int_to_roman(num) function that loops through values and builds the Roman numeral string.Examples
How to Think About It
Algorithm
Code
def int_to_roman(num): val = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] syms = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] roman_num = "" for i in range(len(val)): while num >= val[i]: roman_num += syms[i] num -= val[i] return roman_num print(int_to_roman(1994))
Dry Run
Let's trace the input 1994 through the code
Start with 1994
num = 1994, roman_num = ""
Check 1000 (M)
1994 >= 1000, add 'M', num = 1994 - 1000 = 994, roman_num = 'M'
Check 900 (CM)
994 >= 900, add 'CM', num = 994 - 900 = 94, roman_num = 'MCM'
Check 500 (D)
94 < 500, skip
Check 400 (CD)
94 < 400, skip
Check 100 (C)
94 < 100, skip
Check 90 (XC)
94 >= 90, add 'XC', num = 94 - 90 = 4, roman_num = 'MCMXC'
Check 50 (L)
4 < 50, skip
Check 40 (XL)
4 < 40, skip
Check 10 (X)
4 < 10, skip
Check 9 (IX)
4 < 9, skip
Check 5 (V)
4 < 5, skip
Check 4 (IV)
4 >= 4, add 'IV', num = 4 - 4 = 0, roman_num = 'MCMXCIV'
| Roman Numeral Built |
|---|
| M |
| MCM |
| MCMXC |
| MCMXCIV |
Why This Works
Step 1: Mapping values to symbols
The code uses two lists: one for integer values and one for Roman symbols, ordered from largest to smallest, to match parts of the number.
Step 2: Building the Roman numeral
It repeatedly subtracts the largest possible value from the number and adds the corresponding symbol to the result string.
Step 3: Looping through all values
The loop continues until the number is reduced to zero, ensuring all parts are converted correctly.
Alternative Approaches
def int_to_roman_recursive(num): val = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] syms = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] if num == 0: return "" for i in range(len(val)): if num >= val[i]: return syms[i] + int_to_roman_recursive(num - val[i])
def int_to_roman_dict(num): roman_map = {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'} roman_num = "" for value in sorted(roman_map.keys(), reverse=True): while num >= value: roman_num += roman_map[value] num -= value return roman_num
Complexity: O(n) time, O(1) space
Time Complexity
The algorithm loops through a fixed list of Roman numeral values and subtracts from the number, so it runs in linear time relative to the number of symbols added, which is proportional to the input size.
Space Complexity
Uses a fixed amount of extra space for the symbol lists and the output string, so space is constant relative to input size.
Which Approach is Fastest?
The iterative approach with lists is generally faster and more memory-efficient than recursion, which adds call stack overhead.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Iterative with lists | O(n) | O(1) | Fast and simple conversion |
| Recursive | O(n) | O(n) | Elegant code but less efficient |
| Dictionary mapping | O(n) | O(1) | Flexible mapping, easy to modify |