新的一年,从LeetCode开始吧~【罗马数字与整数的相互转换】

作者: hancao

介绍:本命年的前端工程师

微信:hancao97

背景

春节我从小年就开始请假,完完整整的休息了两周(如果这个文章有人看,请把羡慕两个字打在评论里 ,哈哈哈哈),那两周我本意是我要好好学习天天向上,努力锻炼强健体魄。然而后来发现这些都是扯淡!!!过年在家学习?不存在的,每天就是陪陪父母家人,和家里的小孩子玩。说来也奇怪,原来大学的时候,我不太喜欢小孩子,但是去年工作了,今年回家我就觉得小孩子好可爱,哇,眼睛那么清澈干净,小手小脚那么可爱,真的是让我这个老男人心都融化了,诶呀,我最喜欢小孩子了~(所有人都逃不过真香定律,俺也一样~

所以,既然休息了这么久,我的心肯定早就飘到九霄云外了,我需要调整一下自己的状态开始新的一年,新的一年肯定要元气满满呀,于是从做两道leetcode开始吧,但是我这实力不行加上手都生了,必须选简单的(选简单的说的理直气壮),于是,这个罗马数字和数字的相互转换就深得我心,所以开始吧!!!

罗马数字与整数转换规则介绍

首先我先介绍一下罗马数字,也方便大家了解后续的题目。

罗马数字包含以下七种字符:I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

上面就是罗马数字和整数的对应关系。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: 

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

于是,其实我们可以,修改一下前面的那个表。

字符          数值
I             1
IV            4
V             5
IX            9
X             10
XL            40
L             50
XC            90
C             100
CD            400
D             500
CM            900
M             1000

ok,我们有个这个映射规则,就可以开始做这两道算法题啦!

罗马数字转整数

我们先从简单的罗马数字转整数开始。

先举几个例子:

输入: "III"
输出: 3

输入: "IV"
输出: 4

输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.输入: "MCMXCIV"

输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

ok,这道题其实很简单,整体思路就是一次对输入字符串的遍历,在遍历的过程中有两种情况:

  • 前一个罗马字符比后一个罗马字符对应的整数小,我们就执行减法操作
  • 前一个罗马字符比后一个罗马字符对应的整数大或者相等,我们就执行加法操作

ok!既然这到底思路如此简单,那就直接上代码吧~

var romanToInt = function(s) {
    const ROMON_MAP = new Map([['I', 1],['V', 5],['X', 10],['L', 50],['C', 100],['D', 500],['M', 1000]]);
    const S_LENGTH = s.length;
    let resNum = 0;
    let nextNum = 0;
    let currentNum = ROMON_MAP.get(s[0]);
    for(let index = 1;index < S_LENGTH;index++) {
        nextNum = ROMON_MAP.get(s[index]);
        if(currentNum < nextNum){
            resNum -= currentNum;
        } else {
            resNum += currentNum;
        }
        currentNum = nextNum;
    }
    resNum += currentNum;
    return resNum;
};

 

运行结果:

其实不是很good。我就很sad。

整数转罗马数字

这个就比之前的题目稍微难了一些,leetcode上面的难度也从简单变成了中等,其实也就还好,因为上文提到,我们有了一个新的映射关系!

字符          数值
I             1
IV            4
V             5
IX            9
X             10
XL            40
L             50
XC            90
C             100
CD            400
D             500
CM            900
M             1000

我们先举个例子吧:

输入: 3
输出: "III"
输入: 4
输出: "IV"
输入: 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.
输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.

首先我们得思路是贪心算法,思想是这样的:

每一步都使用当前对应整数较大的罗马字符进行匹配,最后得到罗马数字表示就是长度最少的。

好的说干就干:

var intToRoman = function(num) {
    const NUMS = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
    const ROMON_CHARS = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'];
    let index = 0;
    let romonResStr = '';
    let temp = 0;
    while(index < 13 && num > 0) {
        temp = Math.floor(num/NUMS[index]);
        if(temp>0){
            romonResStr += ROMON_CHARS[index].repeat(temp);
            num -= NUMS[index]*temp; 
        }
        index++;
    }
    return romonResStr;
};

简单讲一下代码吧,首先我们会从较大得罗马字符进行匹配,于是,我建立了两个数组一个是NUMS列表,一个是ROMON_CHARS罗马字符列表,都是从大到小排列得,为什么选用的是数组,因为我在意他们的先后顺序,和之前那个算法不一样,所以之前那个算法我用的数据结构是Map。

之后我们进行了一些初始化,index对应NUMS和ROMON_CHARS的下标,romonResStr是结果字符串,temp变量。

然后开始循环,循环结束条件是index>=13或者num<=0。进入循环体,我们要看当前数值是否是NUMS[index]的整数倍,如果是表示现在的num还大于当前遍历中index指向罗马字符对应的数字,即temp>0。如果temp>0,那么我们就吧当前罗马字符重复temp次,追加到romonResStr中,并执行num -= NUMS[index]*temp。最后index++进入下一次循环。

最后执行结果大概是这样的:

ok,这个代码就讲完了。这两道题还是比较简单,适合新年练练手~

回顾Flag以及总结

诶呀,我之前还是立了很多flag的,今年要去努力实现的,看这个这个,学那个和那个,emmm,搬运以下,列出来吧:

做有主见,有执行力的工程师。


如2021的一月份一样,坚持六点半起床,每天至少两小时的学习时间,并每天锻炼身体30-90分钟【一周至少五次】。


对计算机基础知识的深入学习。【计算机组成原理,编译原理,操作系统等等】(长期,不限于2021)


vue3源码学习。


【英语水平需要加强…】,提升自己获取优质资料并学习能力。


输出12篇高质量博客。【但是我觉得高可能大佬觉得完全不行哈~】


100道leetcode算法题【一月份已完成15道】


提升算法和数据结构水平【系统地读书】(长期,不限于2021)


去西藏!


变成光,迪迦!【抱歉,不正经了!】

 

其实之前列的flag还是好多好多的,但是作为一个工程师这个职业工作已经半年了,感觉其实这是工作,工作的时候也有相应的责任,所以简要的把目标转化成以下几点:

1. 工作中完成高质量高效率的业务支持(工作责任感,这是要做到的最基础最基础的事情)

2. 生活中积极向上,有自己热爱的事情(比如去旅游!),并去做!

3. 个人成长上不局限自己,扩宽,加深,学习不限于前端,还包括计算机基础,以及各种软技能

4. 以及收获爱情就再好不过了,但是我感觉我还年轻,不着急

美好的祝愿

希望大家工作顺利!

希望大家健健康康!

希望大家开开心心!

希望大家都有自信有勇气!

希望大家都可以认识更多有温度的人!

希望大家都有热爱并向去追寻的目标!

希望大家(主要是我)找到命中注定的人!

希望世界和平!

...

新的一年的工作开始啦!!

专注!

加油呀!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值