写在前面:
记录LeetCode练习过程,有自己的解决方法,也有借鉴了网上后实现的方法。方法不一定最优秀,但都是实践可用的。一些解释和理解写在程序起始的注释中。若有什么不当之处,欢迎留言交流,大家一起学习。
import java.util.HashMap;
import java.util.Map;
/**
* LeetCode 0012 整数转罗马数字
* author: MammothKan
* time: 2020/5/2
* 题目描述:https://leetcode-cn.com/problems/integer-to-roman/
* 解题思路:
* 在程序开始之初,构建罗马数字与阿拉伯数字的对应关系,方法一借助了hashMap的键值对形式,方法二借助了两个数组。
* 方法一:通过取余法,获得阿拉伯数字的每一位,再针对每一位转化为罗马数字。程序中每次都取阿拉伯数字的最后一位,再借助一个变量e标记当前位是百位or千位or其他...
* 方法二:采用贪心的思想,每一次取出可以转化的最大数,做转换。所以对程序起始时的两个数组有顺序要求,此处采用的降序。
* 以上两个方法,方法一从右往左按位处理,leetcode消耗时长11ms;方法二采用贪心策略,先处理最大可处理的值,leetcode消耗时长为5ms。
*/
public class L0012整数转罗马数字 {
/**
* 方法一
* @param num
* @return
*/
public String intToRoman(int num) {
String romanInt = "";
Map<Integer, String> romanIntMap = new HashMap(){{
put(1, "I");
put(4, "IV");
put(5, "V");
put(9, "IX");
put(10, "X");
put(40, "XL");
put(50, "L");
put(90, "XC");
put(100, "C");
put(400, "CD");
put(500, "D");
put(900, "CM");
put(1000, "M");
}};
int e = 1;
while (num != 0) {
String thisRomanInt = "";
int thisNum = num % 10;
if ((thisRomanInt = romanIntMap.get(thisNum * e)) != null) { }
else if (thisNum < 4) {
thisRomanInt = "";
for (int i=0; i<thisNum; i++) {
thisRomanInt += romanIntMap.get(e);
}
}
else {
thisRomanInt = romanIntMap.get(5*e);
for (int i=0; i<thisNum-5; i++) {
thisRomanInt += romanIntMap.get(e);
}
}
romanInt = thisRomanInt + romanInt;
num /= 10;
e *= 10;
}
return romanInt;
}
/**
* 方法二
* @param num
*/
public static String intToRoman2(int num) {
int[] numArray = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romanIntArray = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
int index = 0;
StringBuffer romanIntSB = new StringBuffer();
while (num > 0){
if ((num - numArray[index++]) >= 0) {
romanIntSB.append(romanIntArray[--index]);
num -= numArray[index];
}
}
return romanIntSB.toString();
}
public static void main(String[] args) {
System.out.println(new L0012整数转罗马数字().intToRoman(1994));
System.out.println(new L0012整数转罗马数字().intToRoman2(1994));
}
}