Leetcode12:Integer to Roman
题目描述:Integer to Roman
简而言之,将1-3999的数字转变为罗马数字。
可以使用分解因子的方法,结合贪心思想解决问题
解题过程
仔细看了几遍题目,完全没有想出巧妙的解决方法,就按自己的理解写了算法,竟然也过了。
主要就是把1,5,4,9这几种情况考虑全面,然后因为个,十,百,千……都是一样的规律,所以可以作为参数传入函数。虽然可行,但是冗余的判断条件太多,扩展性太差。
public String intToRoman(int num) {
String resultString="";
if (num==0) {
return resultString;
}
if (num<10) {
return getUnits(num,"I","V","X");
}
int i=1;
int temp=num;
while(temp/10!=0) {
i++;
temp/=10;
}
while (i>0) {
switch (i) {
case 4:
temp=num/1000;
num=num%1000;
resultString=resultString+getUnits(temp,"M","","");
break;
case 3:
temp=num/100;
num=num%100;
resultString=resultString+getUnits(temp,"C","D","M");
break;
case 2:
temp=num/10;
num=num%10;
resultString=resultString+getUnits(temp,"X","L","C");
break;
case 1:
temp=num;
resultString+=getUnits(temp,"I","V","X");
break;
default:
break;
}
i--;
}
return resultString;
}
public String getUnits(int num, String sign,String fiveSign,String tenSign) {
String unitString="";
if (num<4&&num>0) {
for (int i = 0; i < num; i++) {
unitString+=sign;
}
}
else if (num==4) {
unitString=unitString+sign+fiveSign;
}
else if (num>4&&num<9) {
unitString=fiveSign;
for(int i=0;i<num-5;i++) {
unitString+=sign;
}
}
else if (num==9) {
unitString=unitString+sign+tenSign;
}
return unitString;
}
看了题解后,恍然大悟:
罗马数字 | 阿拉伯数字 |
---|---|
M | 1000 |
CM | 900 |
D | 500 |
CD | 400 |
C | 100 |
XC | 90 |
L | 50 |
XL | 40 |
X | 10 |
IX | 9 |
V | 5 |
IV | 4 |
I | 1 |
可以把罗马数字当作上表中的各个因子之和,即使用上表右边的数字作为加法因子去分解一个整数,并且所使用的整数越少越好。那么可以考虑为一个“贪心”问题,每次用这个整数减去最大的数。
题解的方法,更易扩展,而且思维更加巧妙。最少纸币应该也可以用这个方法。
public String intToRoman(int num) {
int[] nums = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
String reString="";
int i=0;
int temp=num;
while (i<nums.length) {
while (temp>=nums[i]) {
reString+=romans[i];
temp-=nums[i];
}
i++;
}
return reString;
}