LEETCODE专题
12. Integer to Roman
题目要求:
题目相信大家都看得懂,下面就来直接说一下笔者遇到的问题吧。
- 问题
- 如何将对应的位数转为罗马数字。
- 遇到4, 9的情况如何区分。
这里来简单科普一下罗马数字的字符表示:
十进制数字 | 罗马数字 |
---|---|
1 | I |
4 | IV |
5 | V |
9 | IX |
10 | X |
40 | XL |
50 | L |
90 | XC |
100 | C |
400 | CD |
500 | D |
900 | CM |
1000 | M |
所以对于每个位数的数字,其罗马数字字符都是不一样的,其规则也是具有5和10的双重判定。
为了解决这个问题,我们可以自行定义这些映射,再在转罗马数字的时候调用这个映射就可以了。
这样第一个问题就迎刃而解了。
然而棘手的是第二个问题。
从表中我们可以看到当数字为4或者9时起罗马数字是有异同点的。相同的点就是位数一致时,他们的罗马数字第一个字符都是一样的,都是该位数的单位值。例如40和90的罗马数字第一个字符就是表示10的”X”,10即该位数的单位值。不同的点是它们罗马数字的第二个字符不一样。但是,我们也可以看出规律,例如40的罗马数字第二个字符就是表示50的”L”,而90的罗马数字第二个字符就是表示100的”C”。这样问题就简单多了,我们可以判定数字为4时,字符串为该位数的单位值加上该位数表示5的罗马数字字符;数字为9时,字符串为该位数的单位值加上该位数表示10的罗马数字字符。
class Solution {
public:
string intToRoman(int num) {
/* mod the num with 1000, 500 or so
* and set the Roman char
*/
int mod = 1000;
char weight;
// stroe the Roman string
string Roman;
while (num != 0 && mod != 0) {
weight = getWeight(mod);
if (modHalf(mod) == true) {
// exception handler for 9
if (num / (mod / 5) == 9) {
Roman += getWeight(mod / 5);
Roman += getWeight(mod * 2);
num %= mod / 5;
mod = getNextMod(getNextMod(mod));
continue;
}
} else {
// exception handler for 4
if (num / mod == 4) {
Roman += getWeight(mod);
Roman += getWeight(mod * 5);
num %= mod;
mod = getNextMod(mod);
continue;
}
}
for (int i = 0; i < num / mod; i++) {
Roman += getWeight(mod);
}
num %= mod;
mod = getNextMod(mod);
}
return Roman;
}
bool modHalf(int mod) {
return mod == 5 || mod == 50 || mod == 500;
}
int getNextMod(int mod) {
switch(mod) {
case 1000:
return 500;
case 500:
return 100;
case 100:
return 50;
case 50:
return 10;
case 10:
return 5;
case 5:
return 1;
default:
return 0;
}
}
char getWeight(int mod) {
switch(mod) {
case 1000:
return 'M';
case 500:
return 'D';
case 100:
return 'C';
case 50:
return 'L';
case 10:
return 'X';
case 5:
return 'V';
case 1:
default:
return 'I';
}
}
};
时间复杂度:O(n)