zoukankan      html  css  js  c++  java
  • No.012:Integer to Roman

    题目:

    Given an integer, convert it to a roman numeral.
    Input is guaranteed to be within the range from 1 to 3999.

    官方难度:

    Medium

    翻译:

    给定一个范围在1-3999内的整数,将其转化成罗马数字。

    补充资料:

    罗马数字规则:

    • 需要用到的罗马数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。罗马数字中没有0。
    • 一个罗马数字最多重复3次。
    • 右加左减:
      在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。
      在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
    • 左减的数字有限制,仅限于I、X、C,且放在大数的左边只能用一个。
      (*) V 和 X 左边的小数字只能用I。
      (*) L 和 C 左边的小数字只能用X。
      (*) D 和 M 左 边的小数字只能用C。

    方法一:

    1. 利用一个二维数组,可以很清晰直观地根据维度来记录罗马字符。
    2. 获取最高位数,根据当前所在位置,对应二维数组的维度。
    3. 获取当前数字,4和9需要特殊处理。
    4. 判断当前数字是否大于等于5,将5对应的罗马字符加入结果字符串。
    5. 计算当前数字除以5的余数,累加1对应的罗马字符。
    6. 入参检查。

    方法一的解题代码:

     1         // 使用二维数组,存储罗马字符集
     2     private static String method(int num) {
     3         StringBuffer result = new StringBuffer();
     4         // 罗马字符集
     5         char[][] roman = new char[][] { { 'I', 'V' }, { 'X', 'L' }, { 'C', 'D' }, { 'M' } };
     6         // 确定最高位数
     7         int length = String.valueOf(num).length();
     8         while (length-- > 0) {
     9             // 罗马数字从左往右是最高位的
    10             int current = (int) ((num / Math.pow(10, length)) % 10);
    11             // 4、9特殊处理
    12             if (current == 4) {
    13                 result.append("" + roman[length][0] + roman[length][1]);
    14             } else if (current == 9) {
    15                 result.append("" + roman[length][0] + roman[length + 1][0]);
    16             } else {
    17                 // 大于等于5处理
    18                 if (current / 5 == 1) {
    19                     result.append(roman[length][1]);
    20                 }
    21                 // 加1
    22                 for (int i = 0; i < current % 5; i++) {
    23                     result.append(roman[length][0]);
    24                 }
    25             }
    26         }
    27         return result.toString();
    28     }
    method

    方法二:

    1. 方法一中使用到了二维数组,可以直观地得到罗马字符,但是二维数组的存储效率是很低的。在Java中,没有二维数组的原生态概念,我们所谓的“二维数组”,其本质是数组的数组,这和C里面不同。Java中使用二维数组,无论是在存储空间还是读取速度方面,都有比较大的劣势,在有等效替代的方法情况下,尽量不要使用二维数组。
    2. 题中的二维数组是2*4的,对于m*n的二维数组,可以使用一维数组代替,下标索引的计算,可以参考m进制的加法原理。

    方法二的解题代码:

     1     public static String intToRoman(int num) {
     2         if (num > 3999 || num < 1) {
     3             throw new IllegalArgumentException("Input error");
     4         }
     5         StringBuffer result = new StringBuffer();
     6         // 确定最高位数
     7         int length = String.valueOf(num).length();
     8         while (length-- > 0) {
     9             // 罗马数字从左往右是最高位的
    10             int current = (int) ((num / Math.pow(10, length)) % 10);
    11             // 4、9特殊处理
    12             if (current == 4) {
    13                 result.append("" + romanDict(length, 0) + romanDict(length, 1));
    14             } else if (current == 9) {
    15                 result.append("" + romanDict(length, 0) + romanDict(length + 1, 0));
    16             } else {
    17                 // 大于等于5处理
    18                 if (current / 5 == 1) {
    19                     result.append(romanDict(length, 1));
    20                 }
    21                 // 加1
    22                 for (int i = 0; i < current % 5; i++) {
    23                     result.append(romanDict(length, 0));
    24                 }
    25             }
    26         }
    27         return result.toString();
    28     }
    29 
    30     // 罗马数字字典
    31     private static char romanDict(int x, int y) {
    32         char[] roman = new char[] { 'I', 'V', 'X', 'L', 'C', 'D', 'M' };
    33         return roman[x * 2 + y];
    34     }
    intToRoman

    相关链接:

    https://leetcode.com/problems/integer-to-roman/

    https://github.com/Gerrard-Feng/LeetCode/blob/master/LeetCode/src/com/gerrard/algorithm/medium/Q012.java

    PS:如有不正确或提高效率的方法,欢迎留言,谢谢!

  • 相关阅读:
    前端攻城狮学习笔记九:让你彻底弄清offset
    JavaScript中Element与Node的区别,children与childNodes的区别
    JavaScript代码优化实战之一:缓存变量,关键字过滤
    【转】纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等),NB么
    包装对象——JavaScript中原始类型拥有属性的原因
    关于两个容积不同的瓶子中装水可以得到哪些精确值的问题的算法
    JavaScript中判断鼠标按键(event.button)
    累了休息一会儿吧——分享一个JavaScript版扫雷游戏
    用CSS让未知高度内容垂直方向居中
    空间换时间,把递归的时间复杂度降低到O(2n)
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/5944776.html
Copyright © 2011-2022 走看看