Integer to Roman

Given an integer, convert it to a roman numeral.

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

意思就是:

给出一个整数 num( 0<=num<=3999),返回其对应的罗马数字表示;

罗马数字有:

I V X L C D M
1 5 10 50 100 500 1000

Solutions

  • 1 Integer to Roman -- 143ms

    • 这个方式不知道为什么很慢,是我第一个想出的几乎相当于暴力的方法。
    class Solution {
    public:
    string intToRoman(int num) {
    if(num<=0||num>3999)return string();
    map<int,string> one,two,three,four; //这里使用的是 Map
    one[0]=""; two[0]=""; three[0]="";
    one[1]="I"; two[1]="X"; three[1]="C"; four[1]="M";
    one[2]="II"; two[2]="XX"; three[2]="CC"; four[2]="MM";
    one[3]="III"; two[3]="XXX"; three[3]="CCC"; four[3]="MMM";
    one[4]="IV"; two[4]="XL"; three[4]="CD";
    one[5]="V"; two[5]="L"; three[5]="D";
    one[6]="VI"; two[6]="LX"; three[6]="DC";
    one[7]="VII"; two[7]="LXX"; three[7]="DCC";
    one[8]="VIII"; two[8]="LXXX"; three[8]="DCCC";
    one[9]="IX"; two[9]="XC"; three[9]="CM"; int mod=0,idx=1;
    string rs="",tmp="";
    while(num>0){
    mod=num%10;
    switch(idx){
    case 1:{
    tmp=one[mod];
    rs=tmp+rs;
    break;
    }
    case 2:{
    tmp=two[mod];
    rs=tmp+rs;
    break;
    }
    case 3:{
    tmp=three[mod];
    rs=tmp+rs;
    break;
    }
    case 4:{
    tmp=four[mod];
    rs=tmp+rs;
    break;
    }
    }
    num=num/10;
    ++idx;
    }
    return rs;
    }
    };

    后来经过了测试,发现貌似主要原因在于使用了 map,所以在第二次测试中将 map 改为了 string 数组

  • 2 Integer to Roman -- 68ms

    • 果然,改进后,运行时间从原来的 143ms 变成了 68ms ,这是第一个改进:
    //原来的 map
    map<int,string> one,two,three,four; //这里使用的是 Map
    //改进后
    string* one=new string[10],*two=new string[10],*three=new string[10],*four=new string[4];
  • 3 Integer to Roman -- 54ms

    • 方法1和2中,使用了很大的空间来存储全部的罗马特殊数字,增加了空间复杂性,所以我就想,能不能不存储这些特殊数字,只存储最基本的罗马基数数字 IVXLCDM ,然后根据当前数字进行判断,生成对应的罗马数字。下面是这一思想的代码:
    class Solution {
    public:
    string intToRoman(int num) {
    if(num<=0||num>3999)return string();
    string roman="IVXLCDM"; //存储基数
    string rs="",tmp="";
    int ndx=0,mod=0; // ndx 用来记录当前基数(即第n位对应的最小罗马数字坐标)
    while(num>0){
    mod=num%10; //求余数
    if(ndx==6){ //千位只有 M
    rs=string(mod,'M')+rs;
    break;
    }
    if(mod==0){
    tmp="";
    }else if(mod<4){
    tmp=string(mod,roman[ndx]);
    }else if(mod==4){
    tmp=string(1,roman[ndx])+string(1,roman[ndx+1]);
    }else if(mod<9){
    tmp=string(1,roman[ndx+1])+string(mod-5,roman[ndx]);
    }else if(mod==9){
    tmp=string(1,roman[ndx])+string(1,roman[ndx+2]);
    }
    rs=tmp+rs;
    ndx+=2; //基数向前进2个
    num/=10;
    }
    return rs;
    }
    };
    • 这一思想中,有两点是需要考虑的:

      1. 千位只有 M
      2. 数字4 , 9很特殊;
    • 对于数字 4 来说,如果当前基数坐标为 ndx ,则其对应的罗马数字为:
    string(1,roman[ndx])+string(1,roman[ndx+1]);

    比如当前位为十位,则 ndx=2; roman[ndx]='X'; roman[ndx+1]='L' ; 对应罗马数字为: XL

    • 对于数字 9 来说,对应罗马数字为:
    string(1,roman[ndx])+string(1,roman[ndx+2]);

    比如当前位为十位,则 ndx=2; roman[ndx]='X'; roman[ndx+2]='C' ; 对应罗马数字为: XC

    • 小于 4 的数字 mod,则为 mod 个连续基数;
    • 大于 4 小于 9 的数字 mod , 则为 一个 roman[ndx+1]mode-5 个连续基数;
    • 同时,这个版本中,我发觉还是可以改进一下的,对于代码的改进,所以出现了方法4
  • 4 Integer to Roman -- 48ms

    • 对于代码的进行,方法3中会产生大量的string临时变量,因此这里尽量的使用了迭代器和 string 的insert方法进行处理。代码运行效率得以再次提高:48ms
    class Solution {
    public:
    string intToRoman(int num) {
    if(num<=0||num>3999)return string();
    char roman[]="IVXLCDM";
    string rs="";
    int ndx=0,mod=0;
    while(num>0){
    mod=num%10;
    if(ndx==6){
    rs=string(mod,'M')+rs;
    break;
    }
    if(mod<4){
    rs=string(mod,roman[ndx])+rs;
    }else if(mod==4){
    rs.insert(rs.begin(),roman[ndx+1]);
    rs.insert(rs.begin(),roman[ndx]);
    // rs=string(1,roman[ndx])+string(1,roman[ndx+1])+rs;
    }else if(mod<9){
    // rs=string(1,roman[ndx+1])+string(mod-5,roman[ndx])+rs;
    rs=string(mod-5,roman[ndx])+rs;
    rs.insert(rs.begin(),roman[ndx+1]);
    }else if(mod==9){
    rs.insert(rs.begin(),roman[ndx+2]);
    rs.insert(rs.begin(),roman[ndx]);
    // rs=string(1,roman[ndx])+string(1,roman[ndx+2])+rs;
    }
    ndx+=2;
    num/=10;
    }
    return rs;
    }
    };
  • 5 Integer to Roman -- 57ms

    • 这是LeetCode上网友的答案,感觉跟简洁,同时算法也很容易理解,和这里第一种的思想很像:
    class Solution {
    public:
    string intToRoman(int num) {
    string M[] = {"", "M", "MM", "MMM"};
    string C[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
    string X[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
    string I[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
    return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];
    }
    };
    • 但这里有一个问题,就是这种方法的思想和第二种很像,但是运行时间却更少,于是我将第二种的方法又进行了改进,我感觉差异应该是出现在:第二种方法在赋值时是先定义后赋值,且使用了 new 操作符,这里没有!所以有了下一个简单的改进:
    • 方法二的四个字符串数组,使用方法 5 的方式定义赋值。运行后时间为 58ms,果然这个是原因!看来以后对于内容不是很多的字符数组应该优先不使用 new ,这里还要注意的是,我在第二种方法里 new 的那些个字符数组~~~,忘了一个很重要的操作:delete

      LeetCodeOJ刷题之12【Integer to Roman】的更多相关文章

      1. 【leetcode刷题笔记】Integer to Roman

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

      2. leetCode练题——12. Integer to Roman

        1.题目 12. Integer to Roman Roman numerals are represented by seven different symbols: I, V, X, L, C,  ...

      3. leecode刷题(12)-- 整数反转

        leecode刷题(12)-- 整数反转 整数反转 描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: - ...

      4. Leetcode 12——Integer to Roman

        12.Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be withi ...

      5. Leetcode 12. Integer to Roman(打表,水)

        12. Integer to Roman Medium Roman numerals are represented by seven different symbols: I, V, X, L, C ...

      6. 《LeetBook》leetcode题解(12):Integer to Roman[M]

        我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

      7. LeetCode刷题笔记 - 12. 整数转罗马数字

        学好算法很重要,然后要学好算法,大量的练习是必不可少的,LeetCode是我经常去的一个刷题网站,上面的题目非常详细,各个标签的题目都有,可以整体练习,本公众号后续会带大家做一做上面的算法题. 官方链 ...

      8. 【LeetCode】12. Integer to Roman (2 solutions)

        Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within t ...

      9. LeetCodeOJ刷题之13【Roman to Integer】

        Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within t ...

      随机推荐

      1. Linux软件安装的补充

        1 使用yum 命令查看软件提供的版本 yum list mysql* 然后比如说都需要安装我们就可以执行命令: yum install mysql* 然后就会安装所有的.会显示所有需要安装的包,和需 ...

      2. 32位x86处理器编程导入——《x86汇编语言:从实模式到保护模式》读书笔记08

        在说正题之前,我们先看2个概念. 1.指令集架构(ISA) ISA 的全称是 instruction set architecture,中文就是指令集架构,是指对程序员实际"可见" ...

      3. Hash索引和B+树索引总结

        先说Hash索引 在理想的情况下,key非常分散,不存在Hash碰撞的话,采用Hash索引可以唯一得确定一个key的位置,并且这个位置上就只有一个key,所以查找时间复杂度是O(1),非常快,这是Ha ...

      4. 九度oj题目1153:括号匹配问题

        题目1153:括号匹配问题 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4866 解决:2112 题目描述: 在某个字符串(长度不超过100)中有左括号.右括号和大小写字母:规定(与常见 ...

      5. 如何运营亿级QPS的Redis系统

        欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:冯伟源,高级工程师,腾讯云Redis系统运维负责人.6年DBA经验,一直从事SQL优化.实例调优.数据库架构.海量数据库集群运维.运营 ...

      6. BJFU 1549 ——Candy——————【想法题】

        Candy 时间限制(C/C++):1000MS/3000MS          运行内存限制:65536KByte总提交:40            测试通过:20 描述 There are N c ...

      7. iis6、iis7、apache设置mime类型

        1.IIS6添加方法. 打开iis,展开网站,右键要设置的站点--属性.找到“http头”选项卡--mime类型 进行设置添加. 截图以.ipa mime类型举例. 2.IIS7(iis7.5.iis ...

      8. Android界面编程--使用活动条(ActionBar)--添加Action View

        ActionBar除了显示Action Item 外,还能显示普通的ui组件 2种方式添加Action View 1.指定ActionView的实现类 2.指定ActionView对应的视图资源 实现 ...

      9. 【学习笔记】关于DOM4J:使用DOM4J解析XML文档

        一.概述 DOM4J是一个易用的.开源的库,用于XML.XPath和XSLT中.采用了Java集合框架并完全支持DOM.SAX.和JAXP. DOM4J最大的特色是使用大量的接口,主要接口都在org. ...

      10. express 请求跨域后端解决方法CORS

        CORS全称Cross-Origin Resource Sharing,是HTML5规范定义的如何跨域访问资源. Origin表示本域,也就是浏览器当前页面的域.当JavaScript向外域(如sin ...