12. 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:
Example 3:
Input: num = 1994
Output: "MCMXCIV"
Explanation:
Constraints:
1 <= num <= 3999
Solution:
I = 1
II = 2
III = 3
IV = 4 (-1 + 5)
V = 5
VI = 6
VII = 7
VIII = 8
IX = 9 (- 1 + 10)
X = 10
...
L = 50
C = 100
D = 500
M = 1000
class Solution {
public String intToRoman(int num) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "I");
map.put(4, "IV");
map.put(5, "V");
map.put(9, "IX");
map.put(10, "X");
map.put(40, "XL"); // (-10 + 50)
map.put(50, "L");
map.put(90, "XC");
map.put(100, "C");
map.put(400, "CD");
map.put(500, "D");
map.put(900, "CM");
map.put(1000, "M");
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
StringBuilder sb = new StringBuilder();
for (int v : values){
while(num >= v){
sb.append(map.get(v));
num = num - v;
}
}
return sb.toString();
}
}
/*
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
num = 3749
M M. M D C C. X L I. X
1000 + 1000 + 1000 + 500 + 100 + 100 + 10 + 50 + 1 + 10
s
f
if ( f > s) - > cur. + (f -
*/
// TC: O(n)
// SC: O(1)
class Solution {
public String intToRoman(int num) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "I");
map.put(4, "IV");
map.put(5, "V");
map.put(9, "IX");
map.put(10, "X");
map.put(40, "XL"); // (-10 + 50)
map.put(50, "L");
map.put(90, "XC");
map.put(100, "C");
map.put(400, "CD");
map.put(500, "D");
map.put(900, "CM");
map.put(1000, "M");
StringBuilder sb = new StringBuilder();
int time = 1000;
// 3749
while(time > 0){
int curD = num;
num = num;
if (time != 0){
curD = num / time; // 3749 /1000 = 3
num = num % time; // 749
}
if (curD == 0){
time = time / 10;
continue;
}
/*
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 (curD != 4 && curD != 9){
if (curD == 5){
sb.append(map.get(5 * time));
}
if (curD < 4){
for (int i = 0; i < curD; i++){
sb.append(map.get(time));// 3
// 1000
}
}
if (curD > 5){
sb.append(map.get(5 * time));
for (int i = 0; i < curD - 5; i++){
sb.append(map.get(time));
}
}
time = time / 10;
}
if (curD == 4){
sb.append(map.get(4 * time));
time = time / 10;
continue;
}
if (curD == 9){
sb.append(map.get(9 * time));
time = time / 10;
continue;
}
}
return sb.toString();
}
}
/*
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
num = 3749
M M. M D C C. X L I. X
1000 + 1000 + 1000 + 500 + 100 + 100 + 10 + 50 + 1 + 10
s
f
if ( f > s) - > cur. + (f -
*/
class Solution {
public String intToRoman(int num) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "I");
map.put(4, "IV");
map.put(5, "V");
map.put(9, "IX");
map.put(10, "X");
map.put(40, "XL"); // (-10 + 50)
map.put(50, "L");
map.put(90, "XC");
map.put(100, "C");
map.put(400, "CD");
map.put(500, "D");
map.put(900, "CM");
map.put(1000, "M");
StringBuilder sb = new StringBuilder();
int time = 1000;
// 3749
while(time > 0){
int curD = num / time;
num = num % time;
if (curD == 0){
time = time / 10;
continue;
}
if (curD == 4){
sb.append(map.get(4 * time));
time = time / 10;
continue;
}else if (curD == 9){
sb.append(map.get(9 * time));
time = time / 10;
continue;
}else{
if (curD >= 5){
sb.append(map.get(5 * time));
curD = curD - 5;
}
for (int i = 0; i < curD; i++){
sb.append(map.get(time));
}
time = time / 10;
}
}
return sb.toString();
}
}
// TC: O(n)
// SC: O(1)