LeetCode--整数转罗马数字

题干:

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

示例 1:

输入: 3
输出: "III"

示例 2:

输入: 4
输出: "IV"

示例 3:

输入: 9
输出: "IX"

示例 4:

输入: 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.

示例 5:

输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.

解答一(思路):

1、先用map集合将罗马数字标识与整数对应值一一存储起来。

2、再从高位到低位(千位~个位)依次将整数转换罗马。

3、考虑边界和特殊数字(4和9)的转换.

优点:能详细依次计算出每个位上的转换,扩展后算法任然可用。

缺点:太繁杂,线性时间复杂度高,空间耗用较大。

class Solution {
    public String intToRoman(int num) {
        String result = "";
        if(num <1 || num >3999){
            return result;
        }
        Map<Integer,String> dataMap = new HashMap<Integer,String>();
        dataMap.put(1,"I");
        dataMap.put(5,"V");
        dataMap.put(10,"X");
        dataMap.put(50,"L");
        dataMap.put(100,"C");
        dataMap.put(500,"D");
        dataMap.put(1000,"M");
        int g = num%10;  //个位
        int sw = num/10%10;  //十位
        int b = num/100%10;   //百位
        int q = num/1000%10;  //千位

        //千位
        if(q >0){
            for(int i=1;i<=q;i++){
                result += dataMap.get(1000); 
            }
        }
        //百位
        if(b >0 ){
            if(b == 4){
                result += dataMap.get(100);
                result += dataMap.get(500);
            }else if(b < 4){
                for(int i =1;i<=b;i++){
                    result += dataMap.get(100);
                }
            }else if(9>b && b>4){
                String tmp = dataMap.get(500);
                for(int j=6;j<=b;j++){
                    tmp += dataMap.get(100);
                }
                result += tmp;
            }else if(b ==9){
                result += dataMap.get(100);
                result += dataMap.get(1000);
            }
        }
        //十位
        if(sw >0){
            if(sw == 4){
                result += dataMap.get(10);
                result += dataMap.get(50);
            }else if(sw <4){
                for(int i=1;i<=sw;i++){
                    result += dataMap.get(10);
                }
            }else if(sw<9 && sw>4){
                String tmp = dataMap.get(50);
                for(int j=6;j<=sw;j++){
                    tmp += dataMap.get(10);
                }
                result += tmp;
            }else if(sw ==9){
                result += dataMap.get(10);
                result += dataMap.get(100);
            }    
        }
        //个位
        if(g > 0){
            if(g == 4){
                result += dataMap.get(1);
                result += dataMap.get(5);
            }else if(g<4){
                for(int i=1;i<=g;i++){
                    result += dataMap.get(1);
                }
            }else if(g<9 && g>4){
                String tmp = dataMap.get(5);
                for(int j=6;j<=g;j++){
                    tmp += dataMap.get(1);
                }
                result += tmp;
            }else if(g ==9){
                result += dataMap.get(1);
                result += dataMap.get(10);
            }
        }
        return result;
    }
}

解答二(思路):

1、将所有特殊整点位数的罗马数字和整数,分别用字符串数组和int数组初始化(从大至小)。

2、循环并比较整数int数组与输入需转换目标整数的大小,如果目标>=int[i]则依次减掉目标大于int数组的值,结果字符串拼接对应罗马数字。

优点:线性时间和空间复杂度较低,简洁易读;算法较优。

缺点:如果目标数字过大,并且罗马数字表示负责的话,加大了初始化整数数组和罗马字符数组工作,并易遗漏。

class Solution {
    public String intToRoman(int num) {
        int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
        String reps[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
        StringBuffer sb=new StringBuffer();
        for(int i=0; i<13; i++){
            while(num>=values[i]){
                num -= values[i];
                sb.append(reps[i]);
            }
        }
        return sb.toString();
    }
}
关注公众号:nick_coding1024

觉得对你有帮助,关注博客和公众号。不定期分享最新前沿技术框架和bat大厂常用技术等,加群不定期分享行业内大牛直播讲课以及获得视频课件资料等。

猜你喜欢

转载自blog.csdn.net/Follow_24/article/details/88707198