• LeetCode 13: Roman to Integer


    Given a roman numeral, convert it to an integer.

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

    关于罗马数字介绍(以下内容摘自维基百科):

    罗马数字共有7个,即Ⅰ(1)、Ⅴ(5)、Ⅹ(10)、Ⅼ(50)、Ⅽ(100)、Ⅾ(500)和Ⅿ(1000)。按照下述的规则可以表示任意正整数。

    • 重复数次:一个罗马数字重复几次,就表示这个数的几倍。
    • 右加左减:
      • 在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。
      • 在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
      • 左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
      • 但是,左减时不可跨越一个位值。比如,99不可以用IC(100 - 1)表示,而是用XCIX((100 - 10) + (10 -  1))表示。
      • 左减数字必须为一位,比如8写成VIII,而非IIX。
      • 右加数字不可连续超过三位,比如14写成XIV,而非XIIII。
    • 加线乘千:
      • 在罗马数字的上方加上一条横线或者加下标的Ⅿ,表示将这个数乘以1000,即是原数的1000倍。
      • 同理,如果上方有两条横线,即是原数的1000000倍。
    • 数码限制:
      • 同一数码最多只能连续出现三次,如40不可表示为XXXX,而要表示为XL。

    思路:题中数字范围为1-3999,因此不会出现加上划线的情况。利用左减数字必须为一位,即放在大数前面的小数只能有一个,因此在比较当前数字时,只需考虑其后面的一位。如果当前数字小于它后面的数字,则加上当前数字;否则就减去当前数字。

    解法1:利用map接口,但时间复杂度高

    public int romanToInt(String s){
            int num = 0;
            char[] chars = s.toCharArray();
            Map<Character, Integer> map = new HashMap<>();
            map.put('I',1);map.put('V', 5);map.put('X', 10);
            map.put('L', 50);map.put('C', 100);map.put('D', 500);map.put('M', 1000);
            for(int i = 0; i < chars.length; i++){
                if(i == chars.length - 1 || map.get(chars[i]) >= map.get(chars[i + 1]))
                    num += map.get(chars[i]);
                else
                    num -= map.get(chars[i]);
            }
            return num;
        }

    解法2:

    public int romanToInt(String s){
            int num = 0;
            int current;
            char[] chars = s.toCharArray();
            for(int i = 0; i < chars.length; i++){
                current = charToInt(chars[i]);
            //如果当前数字是最后一个数字,或当前数字大于它后面的数字,则加上当前数字
    if(i == chars.length - 1 || current >= charToInt(chars[i + 1])) num += current;
            //如果当前数字小于它后面的数字,则减去当前数字
    else num -= current; } return num; } public int charToInt(char ch){ int data = 0; switch(ch){ case 'I': data = 1; break; case 'V': data = 5; break; case 'X': data = 10; break; case 'L': data = 50; break; case 'C': data = 100; break; case 'D': data = 500; break; case 'M': data = 1000; break; } return data; }

    解法3:从前往后遍历字符串,每次都加上其相应的数字;如果当前数字大于它前面的数字,则减去前面数字的二倍

    public int romanToInt(String s){
            int num = charToInt(s.charAt(0)), cur, pre;
            for(int i = 1; i < s.length(); i++){
                cur = charToInt(s.charAt(i));
                pre = charToInt(s.charAt(i - 1));
         num
    += cur; //加上当前数字
           //如果当前数字大于它前面的数字,则减去前面数字的二倍
    if(pre < cur) num -= 2 * pre; } return num; } public int charToInt(char ch){ int data = 0; switch(ch){ case 'I': data = 1; break; case 'V': data = 5; break; case 'X': data = 10; break; case 'L': data = 50; break; case 'C': data = 100; break; case 'D': data = 500; break; case 'M': data = 1000; break; } return data; }
  • 相关阅读:
    Netty相关知识积累
    Java内存管理
    使用nginx-upload-module搭建文件上传服务器
    mysql 5.7自动安装脚本
    CDH5集群搭建
    Linux常用命令
    编译原理要点四
    编译原理要点三
    编译原理要点二:
    编译原理要点
  • 原文地址:https://www.cnblogs.com/zeroingToOne/p/7806639.html
Copyright © 2020-2023  润新知