当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

[Leetcode] Roman to Integer and Integer to Roman 罗马数阿拉伯数转换

作者:小梦 来源: 网络 时间: 2024-01-30 阅读:

Valid Roman Numeral

正则表达式

思路

首先我们要熟悉罗马数的表达方式。M是1000,D是500,C是100,L是50,X是10,V是5,I是1。验证字符串是否是罗马数,我们先看一下有效的罗马数是什么样的,假设该数字小于5000,从千位到个位依次拆解。
千位的表达方式 M{0,4}

MMMM      4000MMM       3000MM        2000M         1000

百位的表达方式 (CM|CD|D?C{0,3})

CM        900DCCC      800DCC       700DC        600D         500CD        400CCC       300CC        200C         100

十位的表达方式 (XC|XL|L?X{0,3})

XC        90LXXX      80LXX       70LX        60L         50XL        40XXX       30XX        20X         10

个位的表达方式 (IX|IV|V?I{0,3})

IX        9VIII      8VII       7VI        6V         5IV        4III       3II        2I         1

所以我们正则表达式的就是将这四个部分顺序组合在一起就行了。

注意

  • 罗马数字没有0

  • 正则表达式以^开头,以$结尾

代码

public boolean isRoman(){    if(s.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$")) return true;    return false;}

Roman to Integer

减大加小法

复杂度

时间 O(N) 空间 O(1)

思路

如果我们通过Valid Roman Numeral确定了一个字符串是罗马数字后,我们就可以用一个非常简单的技巧来计算罗马数字的值,而不用考虑那些非法情况。我们知道罗马数字中较小的字母在较大的字母之前意味着较大的字母减去较小的字母,而较小的字母在较大的字母之后意味着较大的字母加上较小的字母。而且这种前面最多只有1个较小字母。所以我们只要在遍历的过程中记住该字母的上一个就行了。如果该字母比上一个小,说明可以直接加上。如果该字母比上一个大,说明正确的值应该是该字母减去上一个字母,而我们之前已经加上了上一个字母,所以我们要减去两倍的上一个字母,然后再加上当前字母。

代码

public class Solution {    public int romanToInt(String s) {        int total = charToInt(s.charAt(0));        for(int i = 1; i < s.length(); i++){int prev = charToInt(s.charAt(i-1));int curr = charToInt(s.charAt(i));if(curr <= prev){    total += curr;} else {    total = total - 2 * prev + curr;}        }        return total;    }    public int charToInt(char c) {        int data = 0;        switch (c) {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;    }}

Integer to Roman

贪心法

复杂度

时间 O(N) 空间 O(1)

思路

因为罗马数字都是由最大化的表示,比如10会表示成X而不是VV,所以我们可以从最大可能的表示向小的依次尝试。因为提示1-3999,所有的可能性不多,我们可以直接打表来帮助我们选择表示方法。在一个数量级中有四种可能的表示方法,以1-9为例,1-3是由I表示出来的,4是IV,5是V,6-8是V和若干个I,9是IX。

代码

public class Solution {    public String intToRoman(int num) {        String[] symbol = {"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};        StringBuilder res = new StringBuilder();        int i = 0;        while(num>0){if(num>=value[i]){    res.append(symbol[i]);    num -= value[i];} else {    i++;}        }        return res.toString();    }}

热点阅读

网友最爱