12. Integer to Roman

12. Integer to Roman

Problem Solving - Day 20

ยท

3 min read

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 to 50 + 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 not IIII. Similarly 9 in roman is not VIIII but rather IX.
  • 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. image.png

  • 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!