{x}
blog image

Integer to Roman

Seven different symbols represent Roman numerals with the following values:

Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

Roman numerals are formed by appending the conversions of decimal place values from highest to lowest. Converting a decimal place value into a Roman numeral has the following rules:

  • If the value does not start with 4 or 9, select the symbol of the maximal value that can be subtracted from the input, append that symbol to the result, subtract its value, and convert the remainder to a Roman numeral.
  • If the value starts with 4 or 9 use the subtractive form representing one symbol subtracted from the following symbol, for example, 4 is 1 (I) less than 5 (V): IV and 9 is 1 (I) less than 10 (X): IX. Only the following subtractive forms are used: 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD) and 900 (CM).
  • Only powers of 10 (I, X, C, M) can be appended consecutively at most 3 times to represent multiples of 10. You cannot append 5 (V), 50 (L), or 500 (D) multiple times. If you need to append a symbol 4 times use the subtractive form.

Given an integer, convert it to a Roman numeral.

 

Example 1:

Input: num = 3749

Output: "MMMDCCXLIX"

Explanation:

3000 = MMM as 1000 (M) + 1000 (M) + 1000 (M)
 700 = DCC as 500 (D) + 100 (C) + 100 (C)
  40 = XL as 10 (X) less of 50 (L)
   9 = IX as 1 (I) less of 10 (X)
Note: 49 is not 1 (I) less of 50 (L) because the conversion is based on decimal places

Example 2:

Input: num = 58

Output: "LVIII"

Explanation:

50 = L
 8 = VIII

Example 3:

Input: num = 1994

Output: "MCMXCIV"

Explanation:

1000 = M
 900 = CM
  90 = XC
   4 = IV

 

Constraints:

  • 1 <= num <= 3999

Solution Explanation: Integer to Roman

This problem involves converting an integer (1 to 3999) into its Roman numeral representation. The solution uses a greedy approach for efficiency.

Approach:

The core idea is to iterate through the Roman numeral symbols from largest to smallest value. For each symbol, we check how many times it can be subtracted from the input integer. This is done repeatedly until the integer becomes zero.

Algorithm:

  1. Initialization: Create two arrays: cs (symbols) and vs (values). cs contains the Roman numeral symbols ("M", "CM", "D", ..., "I") and vs contains their corresponding integer values (1000, 900, 500, ..., 1). The order in vs is crucial; it must be descending to ensure that we use the largest possible symbols first (greedy approach).

  2. Iteration: Iterate through the cs and vs arrays in parallel. For each symbol and its value:

    • Check if the current integer num is greater than or equal to the current value v.
    • While num is greater than or equal to v, subtract v from num and append the corresponding symbol c to the result string (ans).
  3. Return: After the loop finishes, ans will contain the Roman numeral representation of the original integer. Return ans.

Time Complexity: O(1)

Although we have a loop, it iterates a maximum of 13 times (the number of Roman numeral symbols). The number of iterations is fixed and independent of the input integer. Therefore, the time complexity is considered constant, O(1).

Space Complexity: O(1)

The space used by the arrays cs and vs remains constant regardless of the input integer. The space used by the result string ans is also proportional to the length of the Roman numeral representation, which is at most 15 characters (for the number 3888: MMMDCCCLXXXVIII). Since the maximum length is constant, space complexity is O(1).

Code Examples (with detailed comments):

Python:

class Solution:
    def intToRoman(self, num: int) -> str:
        # Roman numeral symbols and their values (descending order is crucial)
        symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]
        values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
        
        result = "" # Initialize the result string
        
        for i in range(len(symbols)): # Iterate through the symbols
            while num >= values[i]: # While we can still subtract the current value
                result += symbols[i] # Append the symbol to the result
                num -= values[i] # Subtract the value from the input number
        return result # Return the Roman numeral string
 

Java:

class Solution {
    public String intToRoman(int num) {
        String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        
        StringBuilder result = new StringBuilder(); // Use StringBuilder for efficient string concatenation
        
        for (int i = 0; i < symbols.length; i++) {
            while (num >= values[i]) {
                result.append(symbols[i]);
                num -= values[i];
            }
        }
        return result.toString();
    }
}

The other languages (C++, Go, TypeScript, Rust, C#, PHP) follow a very similar structure, adapting the syntax and data structures specific to each language. The core algorithm remains the same.