乘风破浪:LeetCode真题_013_Roman to Integer
一、前言
上一节我们讨论了如何把阿拉伯数字转换成罗马数字,现在我们需要思考一下如何把罗马数字转换成阿拉伯数字,其实我们仔细观擦这些结构就会发现罗马数字如果前面的比后面的小,就需要用后面的减去前面的。而且如果有这样的运算,也只是两个字符拼接而成的,这为我们解题提供了思路。
二、Roman to Integer
2.1 问题
2.2 分析与解决
根据题意,我们可以明白只需要从开始到结尾遍历这些罗马数字,如果发现前一个小于后一个代表的数字,则用后面的数值减去前面的数值,然后将这些数值相加在一起,这样就能得到最终的结果了。同样的我们也可以从后往前遍历,如果发现前面的小于后面的就进行减法操作,否则直接相加也是可以的。当然这一切都要依靠于给定的罗马数字是正确的前提下。
于是有了两种方式:从前往后,从后往前。
从前往后:
class Solution { public int romanToInt(String s) { if(s== null) 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 sum = 0; for(int i=0;i<s.length();i++) { if((i+1 < s.length()) && map.get(s.charAt(i+1)) > map.get(s.charAt(i))) { sum = sum + (map.get(s.charAt(i+1)) - map.get(s.charAt(i))); i++; }else{ sum = sum + map.get(s.charAt(i)); } } return sum; } }
从后往前:
public class Solution { /** * 题目大意 * 给定一个罗马数字,将其转换成对应的整数。 * 输入的数字在1-3999之间。 * * 解题思路 * 根据罗马数字与整数数字对应关系进行加法操作,从后向前遍历,如果前一个数字比后一个大就相减,否则进行相加。 */ public int romanToInt(String s) { int result = 0; int prev = 0; // 记录前一个数字的值 for (int i = s.length() - 1; i >= 0; i--) { switch (s.charAt(i)) { case 'I': // 1 if (1 < prev) { result -= 1; } else { result += 1; } prev = 1; break; case 'V': // 5 if (5 < prev) { result -= 5; } else { result += 5; } prev = 5; break; case 'X': // 10 if (10 < prev) { result -= 10; } else { result += 10; } prev = 10; break; case 'L': // 50 if (50 < prev) { result -= 50; } else { result += 50; } prev = 50; break; case 'C': // 100 if (100 < prev) { result -= 100; } else { result += 100; } prev = 100; break; case 'D': // 500 if (500 < prev) { result -= 500; } else { result += 500; } prev = 500; break; case 'M': // 1000 result += 1000; prev = 1000; break; } } return result; } }
三、总结
同样的思路,有的代码写得非常具有条理性,有的写得比较复杂,运行之后的耗时也是不同的,因此需要软件工程技术上的培养。