题目:
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
链接: http://leetcode.com/problems/roman-to-integer/
题解:
public class Solution { public int romanToInt(String s) { // I = 1; V = 5; X = 10; L = 50; C = 100; D = 500; M = 1000; if(s == null || s.length() == 0) return 0; HashMap<Character, Integer> map = new HashMap<Character, Integer>(); map.put('I', 1); map.put('V', 5); map.put('X', 10); map.put('L', 50); map.put('C', 100); map.put('D', 500); map.put('M', 1000); int result = map.get(s.charAt(s.length() - 1)); for(int i = s.length() - 2; i >= 0; i--) { if(map.get(s.charAt(i)) < map.get(s.charAt(i + 1)) ) result -= map.get(s.charAt(i)); else result += map.get(s.charAt(i)); } return result; } }
二刷:
还是使用一个Map把<Character, Integer> pair保存起来,然后从后向前进行遍历。当前值cur比上一个值prev小的时候,减去cur,否则加上cur并且更新prev,要注意边界。也可以用Bitmap来做,可能会比HashMap快一点。
Java:
Time Complexity - O(n), Space Complexity - O(n)
public class Solution { public int romanToInt(String s) { if (s == null || s.length() == 0) { return 0; } Map<Character, Integer> map = new HashMap<>(); map.put('I', 1); map.put('V', 5); map.put('X', 10); map.put('L', 50); map.put('C', 100); map.put('D', 500); map.put('M', 1000); int res = 0, prev = map.get(s.charAt(s.length() - 1)); res += prev; for (int i = s.length() - 2; i >= 0; i--) { int cur = map.get(s.charAt(i)); if (cur < prev) { res -= cur; } else { res += cur; prev = cur; } } return res; } }
Python:
class Solution(object): def romanToInt(self, s): """ :type s: str :rtype: int """ if s is None or len(s) == 0: return 0 res = 0 dict = {'I' : 1, 'V' : 5, 'X' : 10, 'L' : 50, 'C' : 100, 'D' : 500, 'M' : 1000} prev = dict[s[len(s) - 1]] res += prev for c in reversed(s[0 : len(s) - 1]): cur = dict[c] if cur < prev: res -= cur else: res += cur prev = cur return res
三刷:
看不懂前面在写什么....
题目要求转换Roman numerial to Integer。我表示已经把I, V, X, L, C, D和M都背下来了。 先把这些罗马数字和对应的值都保存在一个map里。然后我们思考两个test case。 "IV"代表4, "VI"代表6,那么就是说,较小的数字出现在较大的数字左边时,这里代表两者作差,即 较大数字 - 较小数字,否则代表两者的和。 这样我们就可以从左向右遍历字符串,先设定result = map.get(s.charAt(0)),然后从第一个位置开始遍历, 比较当前字符代表的数字和上一个字符代表的数字,根据我们上面得出的结论来计算。lastNum >= curNum时,我们直接加curNum, 当lastNum < curNum时,我们之前已经加过一次lastNum,所以这时候要加curNum并且减掉两个lastNum。最后返回结果。
使用array来替代map来保存Roman和Int的对应关系的话可以速度更快。
Java:
public class Solution { public int romanToInt(String s) { if (s == null || s.length() == 0) { return 0; } Map<Character, Integer> map = new HashMap<>(); map.put('I', 1); map.put('V', 5); map.put('X', 10); map.put('L', 50); map.put('C', 100); map.put('D', 500); map.put('M', 1000); int res = map.get(s.charAt(0)); int lastNum = res; for (int i = 1; i < s.length(); i++) { int curNum = map.get(s.charAt(i)); if (lastNum >= curNum) { res += curNum; } else { res += curNum - 2 * lastNum; } lastNum = curNum; } return res; } }
简化一下:
public class Solution { public int romanToInt(String s) { if (s == null || s.length() == 0) return 0; Map<Character, Integer> map = new HashMap<>(); map.put('I', 1); map.put('V', 5); map.put('X', 10); map.put('L', 50); map.put('C', 100); map.put('D', 500); map.put('M', 1000); int res = map.get(s.charAt(0)); int lastNum = res; for (int i = 1; i < s.length(); i++) { int curNum = map.get(s.charAt(i)); if (lastNum < curNum) res -= 2 * lastNum; res += curNum; lastNum = curNum; } return res; } }