LeetCode 12 – Integer to Roman

Posted on December 25, 2013

Last updated on December 25, 2013

Solution to LeetCode Integer to Roman problem.

import java.util.TreeMap;

public class Solution {
  /*
Idea: First, convert a number, say 2034, into a list such as [4,30,0,2000].
Then, convert the individual components, and append together.

Rules: A subtractive pair must be of the following type
I followed by V or X
X followed by C or D
C followed by D or M

The rules are applied in order:
- First check if number is one of the numbers in the dictionary
- Then, check if it's possible to create a subtractive pair from it
- If not, finally do a normal conversion
- Take the least greatest than or equal element from the map, use it
, and convert the leftovers
   */

  TreeMap<Integer, String> tm;
  public String intToRoman(int num) {

    if(tm == null){
      tm = new TreeMap<Integer,String>();
      tm.put(1,"I");
      tm.put(5,"V");
      tm.put(10,"X");
      tm.put(50,"L");
      tm.put(100,"C");
      tm.put(500,"D");
      tm.put(1000,"M");            
    }

    String result = "";

    for(int i : convert(num)){
      result = intToRoman(i,tm) + result;
    }

    return result;
  }

  public String intToRoman(int num, TreeMap<Integer,String> tm){
    if(num == 0) return "";
    else if(tm.containsKey(num)) return tm.get(num);
    else{
      // Try subtractive order first
      String s1 = tm.get(num+1);
      String s2 = tm.get(num+10);
      String s3 = tm.get(num+100);

      if(s1 != null && (s1.equals("V") || s1.equals("X"))){
        return "I" + s1;
      }
      else if(s2 != null && (s2.equals("L") || s2.equals("C"))){
        return "X" + s2;
      }
      else if(s3 != null && (s3.equals("D") || s3.equals("M"))){
        return "C" + s3;   
      }
      else{ // no valid subtractive order, make the number normally
        int lt = tm.floorKey(num);
        return tm.get(lt) + intToRoman(num-lt,tm);
      }
    }
  }

  private ArrayList<Integer> convert(int n){
    ArrayList<Integer> res = new ArrayList<Integer>();
    int l = (int)(Math.log(n)/Math.log(10)) + 2;
    for(int i = 10; i <= Math.pow(10,l); i *= 10){
      res.add(n % i);
      n -= n % i;
    }
    return res;
  }

}
Integer to Roman
Markdown SHA1: 0232919a2bdc2ea6cba3e36f8a758c5f75f08f6c