「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
题目:字面含义,整数转罗马数字,罗马数字共七个,分别为I, V, X, L,C,D 和 M。其分别对应1、5、10、50、100、500、1000,除了4和9的一倍、十倍以及百倍为特殊情况,其余数字表示都正常。详细题目看LeetCode 第12题。此处有一个提示,输入的num的取值范围为1~3999。
解题思路
首先看到num的取值范围1~3999,也就是说我们千位只需要关注0-3即可,并且例如数字1994,其对应的输出为"MCMXCIV",拆开即为M + CM + XC + IV,分别对应千位、百位、十位、个位。因此本题的关键点就是将输入的num进行拆分,拆分之后进行简单的判断即可,如果是4和9就进行特殊处理,如果是其他数字则常规拼接。但这样代码可能会出现很多的if else ,代码易读性较差,一种更常规的思路是首先列举出每位所有可能的情况,之后根据各十百千位的不同进行选择即可,之后对选择出的字符进行拼接即为正确结果。
此处列出所有情况选择的数据结构是数组,可以在数组中列举每个位在0~9所有可能的情况,之后根据计算的实际数值,去数组中选择具体的字符,此时就不需要考虑4和9不同位的特殊性了,列举的所有情况如下:
-
对于千位,只需要考虑前四种。
String[] thousands = {"", "M", "MM", "MMM"}; -
百位以及之下则是所有情况:
String[] hundreds = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; -
十位:
String[] tens = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; -
个位:
String[] ones = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};具体代码如下:
public static String intToRoman(int num){ String[] thousands = {"", "M", "MM", "MMM"}; String[] hundreds = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; String[] tens = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; String[] ones = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; int thousand = num / 1000; int hundred = num % 1000 / 100; int ten = num % 100 / 10; int one = num % 10; return thousands[thousand] + hundreds[hundred] + tens[ten] + ones[one]; }
算法的时间复杂度和空间复杂度都是。最终运行结果:
相似题目:罗马数字转阿拉伯数字
本题的题目可见LeetCode第13题。
解题思路
本题思路很关键的一点是将罗马字符串切分开,之后有一个很重要的性质就是切分开后的字符转阿拉伯数字,如果不是4和9特殊情况的话前一个字符数字必然大于后一个,如果不存在这种性质,则表示出现了特殊情况,此时就需要将结果相减一下,代码如下:
private static int getInt(char c){
int num = 0;
switch (c){
case 'I':
num = 1;
break;
case 'V':
num = 5;
break;
case 'X':
num = 10;
break;
case 'L':
num = 50;
break;
case 'C':
num = 100;
break;
case 'D':
num = 500;
break;
case 'M':
num = 1000;
break;
}
return num;
}
public static int RomanToInt(String s){
char[] chars = s.toCharArray();
int RomanNum = 0;
for(int i=0;i<chars.length-1;i++){
int prior = getInt(chars[i]);
int next = getInt(chars[i+1]);
if(prior<next){
RomanNum -= prior;
}else {
RomanNum += prior;
}
}
return RomanNum + getInt(chars[chars.length-1]);
}
总结
两题思路其实不难,主要思想就是列举,看清题意,列举出所有情况即可。