• [LeetCode] 12. Integer to Roman ☆☆


    Given an integer, convert it to a roman numeral.

    Input is guaranteed to be within the range from 1 to 3999.

    解释:

      罗马数字采用七个罗马字母作数字、即Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。记数的方法:

    1. 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3;
    2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12;
    3. 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9;
    4. 在一个数的上面画一条横线,表示这个数增值 1,000 倍(本题不涉及)

      例如:整数 1437 的罗马数字为 MCDXXXVII, 我们不难发现,千位,百位,十位和个位上的数分别用罗马数字表示了。 1000 - M, 400 - CD, 30 - XXX, 7 - VII。所以我们要做的就是用取商法分别提取各个位上的数字,然后分别表示出来:

    100 - C

    200 - CC

    300 - CCC

    400 - CD

    500 - D

    600 - DC

    700 - DCC

    800 - DCCC

    900 - CM

    解法: 

      每次取下最高位上的数字x,判断其范围为 (0-3)、(4)、(5-8)、(9) 中的哪一类,再根据每一类的特点添加字符。

    public class Solution {
        public String intToRoman(int num) {
            StringBuilder res = new StringBuilder("");
            char[] roman = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};
            int[] value = {1000, 500, 100, 50, 10, 5, 1};
            
            for (int i = 0; i < value.length; i += 2) {
                int x = num / value[i];
                if (x < 4) {
                    while (x-- > 0) res.append(roman[i]);
                } else if (x == 4) {
                    res.append(roman[i]).append(roman[i - 1]);
                } else if (x < 9) {
                    res.append(roman[i - 1]);
                    while (x-- > 5) res.append(roman[i]);
                } else {
                    res.append(roman[i]).append(roman[i - 2]);
                }
                num %= value[i];
            }
            return res.toString();
        }
    }

      本题由于限制了输入数字范围这一特殊性,因此也可以采用贪婪算法,建立一个数表,每次通过查表找出当前最大的数并匹配对应的字符串,然后减去再继续查表。代码如下:

    public class Solution {
        public String intToRoman(int num) {
            StringBuilder res = new StringBuilder("");
            String[] roman = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
            int[] value = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
            
            for (int i = 0; i < value.length; i++) {
                int x = num / value[i];
                while (x-- > 0) res.append(roman[i]);
                num %= value[i];
            }
            return res.toString();
        }
    }

      另外,由于限制了输入数字范围,存在的情况有限,还可以把所有的情况都列出来,然后直接按位查表,O(1)的时间复杂度,代码如下:

    public class Solution {
        public String intToRoman(int num) {
            StringBuilder res = new StringBuilder("");
            String[] r1 = {"", "M", "MM", "MMM"};
            String[] r2 = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
            String[] r3 = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
            String[] r4 = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
            
            res.append(r1[num / 1000]).append(r2[(num % 1000) / 100]).append(r3[(num % 100) / 10]).append(r4[(num % 10) / 1]);
            return res.toString();
        }
    }
  • 相关阅读:
    [Erlang 0106] Erlang实现Apple Push Notifications消息推送
    一场推理的盛宴
    [Erlang 0105] Erlang Resources 小站 2013年1月~6月资讯合集
    [Erlang 0104] 当Erlang遇到Solr
    [Erlang 0103] Erlang Resources 资讯小站
    history.go(-1)和History.back()的区别
    [Java代码] Java用pinyin4j根据汉语获取各种格式和需求的拼音
    spring中context:property-placeholder/元素
    Java中的异常处理:何时抛出异常,何时捕获异常?
    用Jersey构建RESTful服务1--HelloWorld
  • 原文地址:https://www.cnblogs.com/strugglion/p/6403775.html
Copyright © 2020-2023  润新知