原题目:
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
将罗马数字转换成阿拉伯数字
算法分析:
算法1:
从前往后扫描,用一个临时变量记录分段数字。
如果当前比前一个大,说明这一段的值应该是当前这个值减去上一个值。比如IV = 5 – 1;否则,将当前值加入到结果中,然后开始下一段记录。比如VI = 5 + 1, II=1+1
算法2:
采用HashMap来存储各种罗马数字,而不是利用 switch case来判断,这样能够节约时间复杂度。
LeetCode提交源码:
算法1:
public int romanToInt(String s){
int result = 0;
for(int i = 0; i < s.length(); i++){
if(i > 0 && map(s.charAt(i)) > map(s.charAt(i-1))){
//因为在下一个else可能会多加一个map(s.charAt(i - 1)),所以此处要减2倍的
//比如IV,第一次i=0,result=s(0)=I=1,第二次i = 1,result = s(1)-2*s(0)=5-2*1=4;
result += (map(s.charAt(i)) - 2*map(s.charAt(i - 1)));
}
else{
result += map(s.charAt(i));
}
}
return result;
}
private static int map(char c){
switch(c){
case 'I' : return 1;
case 'V' : return 5;
case 'X' : return 10;
case 'L' : return 50;
case 'C' : return 100;
case 'D' : return 500;
case 'M' : return 1000;
default : return 0;
}
}
算法2:
public int romanToInt(String s){
if(s == null || s.length() == 0){
return 0;
}
Map<Character,Integer> m = new HashMap<Character,Integer>();
m.put('I',1);
m.put('V',5);
m.put('X',10);
m.put('L',50);
m.put('C',100);
m.put('D',500);
m.put('M',1000);
int length = s.length();
int result = m.get(s.charAt(length - 1));
for(int i = length - 2; i >= 0;i--){
if(m.get(s.charAt(i + 1)) <= m.get(s.charAt(i))){
result += m.get(s.charAt(i));
}
else{
result -= m.get(s.charAt(i));
}
}
return result;
}
完整运行程序:
/**************************************************************
* Copyright (c) 2016
* All rights reserved.
* 版 本 号:v1.0
* 题目描述: Given a roman numeral, convert it to an integer.
* Input is guaranteed to be within the range from 1 to 3999.
* 将罗马数字转化成阿拉伯数字
* 输入描述:请输入一个罗马数字:
* IV
* 程序输出:输入的罗马数字转化为阿拉伯数字的结果为:
* 4
* 算法2的结果为:
* 3586
* 问题分析:无
* 算法描述:算法1:从前往后扫描,用一个临时变量记录分段数字。如果当前比前一个大,
* 说明这一段的值应该是当前这个值减去上一个值。比如IV = 5 – 1;否则,
* 将当前值加入到结果中,然后开始下一段记录。比如VI = 5 + 1, II=1+1
* 算法2:利用Hashmap存储,而不是用switch case 来判断,但判断数字的原理相同
* 完成时间:2016-11-27
***************************************************************/
package org.GuoGuoFighting.LeetCode013;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/*
算法1:算法正确,但LeetCode运行时超时,无法提交
*/
class SolutionMethod1{
public int romanToInt(String s){
int result = 0;
for(int i = 0; i < s.length(); i++){
if(i > 0 && map(s.charAt(i)) > map(s.charAt(i-1))){
//因为在下一个else可能会多加一个map(s.charAt(i - 1)),所以此处要减2倍的
//比如IV,第一次i=0,result=s(0)=I=1,第二次i = 1,result = s(1)-2*s(0)=5-2*1=4;
result += (map(s.charAt(i)) - 2*map(s.charAt(i - 1)));
}
else{
result += map(s.charAt(i));
}
}
return result;
}
private static int map(char c){
switch(c){
case 'I' : return 1;
case 'V' : return 5;
case 'X' : return 10;
case 'L' : return 50;
case 'C' : return 100;
case 'D' : return 500;
case 'M' : return 1000;
default : return 0;
}
}
}
/*
算法2:运用HashMap来存储*/
class SolutionMethod2{
public int romanToInt(String s){
if(s == null || s.length() == 0){
return 0;
}
Map<Character,Integer> m = new HashMap<Character,Integer>();
m.put('I',1);
m.put('V',5);
m.put('X',10);
m.put('L',50);
m.put('C',100);
m.put('D',500);
m.put('M',1000);
int length = s.length();
int result = m.get(s.charAt(length - 1));
for(int i = length - 2; i >= 0;i--){
if(m.get(s.charAt(i + 1)) <= m.get(s.charAt(i))){
result += m.get(s.charAt(i));
}
else{
result -= m.get(s.charAt(i));
}
}
return result;
}
}
public class RomantoInteger {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个罗马数字:");
String str = scanner.nextLine();
scanner.close();
System.out.println("输入的罗马数字转化为阿拉伯数字的结果为:");
SolutionMethod1 solution1 = new SolutionMethod1();
System.out.println(solution1.romanToInt(str));
System.out.println("算法2的结果为:");
SolutionMethod2 solution2 = new SolutionMethod2();
System.out.println(solution2.romanToInt(str));
}
}
程序运行结果: