LeetCodeOJ刷题之12【Integer to Roman】
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
-
- 这个方式不知道为什么很慢,是我第一个想出的几乎相当于暴力的方法。
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 数组
-
- 果然,改进后,运行时间从原来的 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];
-
- 方法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;
}
};
- 这一思想中,有两点是需要考虑的:
- 千位只有
M
; - 数字
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
- 方法1和2中,使用了很大的空间来存储全部的罗马特殊数字,增加了空间复杂性,所以我就想,能不能不存储这些特殊数字,只存储最基本的罗马基数数字
-
- 对于代码的进行,方法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;
}
};
-
- 这是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】的更多相关文章
- 【leetcode刷题笔记】Integer to Roman
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...
- leetCode练题——12. Integer to Roman
1.题目 12. Integer to Roman Roman numerals are represented by seven different symbols: I, V, X, L, C, ...
- leecode刷题(12)-- 整数反转
leecode刷题(12)-- 整数反转 整数反转 描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: - ...
- Leetcode 12——Integer to Roman
12.Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be withi ...
- Leetcode 12. Integer to Roman(打表,水)
12. Integer to Roman Medium Roman numerals are represented by seven different symbols: I, V, X, L, C ...
- 《LeetBook》leetcode题解(12):Integer to Roman[M]
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- LeetCode刷题笔记 - 12. 整数转罗马数字
学好算法很重要,然后要学好算法,大量的练习是必不可少的,LeetCode是我经常去的一个刷题网站,上面的题目非常详细,各个标签的题目都有,可以整体练习,本公众号后续会带大家做一做上面的算法题. 官方链 ...
- 【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 ...
- LeetCodeOJ刷题之13【Roman to Integer】
Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within t ...
随机推荐
- 克隆kvm虚拟机报错ImportError: No module named 'requests.packages.urllib3'
2018-06-21 更新系统造成kvm克隆命令报错 virt-clone -o centos--update-clone -n centos--maven-test -f /var/lib/vmdk ...
- kali 安装命令类
apt-get常用命令:update – 取回更新的软件包列表信息upgrade – 进行一次升级install – 安装新的软件包(注:软件包名称是 libc6 而非 libc6.deb)remov ...
- 参考美团、饿了么 && localStorage
localStorage使用. 为什么要使用 localStorage? 因为在之前的讨论过程中,问题:每次添加一件商品和去掉一个商品都需要发送一个http请求来更新购物车, ...
- (Frontend Newbie)JavaScript基础之函数
函数可以说是任何一门编程语言的核心概念.要能熟练掌握JavaScript,对于函数及其相关概念的学习是非常重要的一步.本篇从函数的基本知识.执行环境与作用域.闭包.this关键字等方面简单介绍Java ...
- SpringBoot | 第三十五章:Mybatis的集成和使用
前言 最近收到公众号留言说,单纯的Mybatis的集成和使用.前面在第九章:Mybatis-plus的集成和使用介绍了基于mybatis-plus的集成和使用.后者也只是对mybatis进行了功能增强 ...
- [转]Using NLog for ASP.NET Core to write custom information to the database
本文转自:https://github.com/NLog/NLog/issues/1366 In the previous versions of NLog it was easily possibl ...
- 针对在webview模式中,小米魅族手机不支持html5原生video的control的解决办法![原创]
其实,解决办法就是,重新写个control控制功能,.同样用流行的video.js可以实现 第一步就是增加个播放的图片..要不然没有按钮多难看! <div class="videoDi ...
- C# 面向对象多态的抽象性&接口 object&is as类型转换运算符
抽象类/抽象方法 abstract 抽象的数据类型 抽象类不能被实例化 抽象类中不一定存在抽象方法 抽象方法一定是在抽象类中 抽象类里可以放任意的方法 接口 interface 不是类,就是用来当爹 ...
- js系列之js简介
该系列教程都来源于:廖雪峰老师的博客 JavaScript是世界上最流行的脚本语言,因为你在电脑.手机.平板上浏览的所有的网页,以及无数基于HTML5的手机App,交互逻辑都是由JavaScript驱 ...
- vuejs的双向数据绑定实现原理——object.defineproperty()
视图和数据变化绑定 而vue.js主要利用了accessor descriptors的set和get来更新视图,这里看到的这个例子挺好,是一个简单的绑定.对于一个html页面 <div> ...
- 【leetcode刷题笔记】Integer to Roman