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:
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
).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
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:
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).
Iteration: Iterate through the cs
and vs
arrays in parallel. For each symbol and its value:
num
is greater than or equal to the current value v
.num
is greater than or equal to v
, subtract v
from num
and append the corresponding symbol c
to the result string (ans
).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.