Hello, reader ๐๐ฝ ! Welcome to day 20 of the series on Problem Solving. Through this series, I aim to pick up at least one question everyday and share my approach for solving it.
Today, I will be picking up LeetCode's daily challenge problem: 12. Integer to Roman.
๐ค Problem Statement
- Given a number, convert it to roman numeral form.
- E.g.:
num = 3
=> `"III"num = 1994
=>"MCMXCIV"
๐ฌ Thought Process
- Intuition says that we can convert a number to it's roman numeral by separating the one's, ten's, hundred's and thousand's place.
- For e.g.
58
can be split to50 + 8
and easily be converted to roman form. - This could have been easily done had it not been for the special cases which are also given in the question.
- For e.g. 4 in roman is
IV
and notIIII
. Similarly 9 in roman is notVIIII
but ratherIX
. - And the same special cases can be observed in 40, 90, 400, and 900.
- Also, we should keep in mind that at numbers 5, 50, and 500, the roman symbol changes in comparison with the previous numbers in 1s, 10s, and 100s places respectively.
- So we will also have to check our number against all the possible places where the change happens:
1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, and 1000
. - That's what we will do, compare the thousands, hundreds, tens, and ones place with the above numbers.
- At any number if the value is less than 0, we move on to the next number and continue until the number is 0.
- To better understand, let's walk through an example first. Let's take the number
2947
. Look at the image below to understand the process.
Let's jump into the code for this now.
๐ฉ๐ฝโ๐ป Solution
- Below is the code for the above discussed approach.
class Solution {
public String intToRoman(int num) {
if(num == 0) {
return "0";
}
String s = "";
String[] mapping = new String[] {
"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
};
int[] places = new int[] {
1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
};
for(int i = 0; i<places.length; i++) {
int place = places[i];
int digit = num / place;
if(digit != 0) {
String symbol = mapping[i];
s+= getRomanSymbol(digit, symbol);
}
num = num % place;
}
return s;
}
private String getRomanSymbol(int n, String symbol) {
StringBuilder sb = new StringBuilder("");
while(n-- > 0) {
sb.append(symbol);
}
return sb.toString();
}
}
Time Complexity: O(x)
- x = maximum of number/place
- while the for loop runs in O(1), the while loop at max runs in `n/place` times, where the symbol at place appears n/place times.
Space Complexity: O(1)
- We are using constant memory to store the places and their symbol mappings.
- There is an O(n) solution to this problem as well, but I won't be sharing it here since it wasn't intuitive for me. You can find that in the discussion forum.
Conclusion
That's a wrap for today's problem. If you liked my explanation then please do drop a like/ comment. Also, please correct me if I've made any mistakes or if you want me to improve something!
Thank you for reading!