string 找出所有数字 index_发现规律,解决整数转罗马数字

68ceba8c99f9f9a6279b6ecc3970af6d.gif

898df2a218a2e3b3ff9e06f34ee3c96b.png

嗨,各位!我们又准时见面了,即将迎来难得的周末时光,我们今天来一道相对简单的题目逻辑梳理的题目,原定的动态规划的常见题型我们放在周末进行更新。话不多说,我们先看题目:  01 . 题目罗马数字包含以下七种字符:I, V, X, L,C,D 和 M。
字符数值
I1
V5
X10
L50
C100
D500
M1000
例如,2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 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。

给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

示例 1:  输入: 3  输出: "III" 
示例 2:  输入: 4  输出: "IV" 
示例 3:  输入: 9  输出: "IX" 
示例 4:  输入: 58  输出: "LVIII" 解释: L = 50, V = 5, III = 3.
示例 5:  输入: 1994  输出: "MCMXCIV" 解释: M = 1000, CM = 900, XC = 90, IV = 4.
02 . 思路分析这道题整体看起来有明确的规则,只需要梳理清楚罗马数字的表示规律即可,那我们现在就开始发现规律:跟我们常用的阿拉伯数字表示十进制数字相同,罗马数字也通过十进制来表示,只是比我们的 0 1 2 3 4 5 的阿拉伯数字复杂一些,而且每一位用的是不同的字母表示。我们先把 0 - 9 的罗马数字拿出来找规律:
0123456789
IIIIIIIVVVIVIIVIIIIX
我们发现了如下规律:
  • 0 ~3  就是 0 到 3 个 罗马数字 ‘‘I’’ 表示
  • 4 就是 5 - 1 但是减数放在了前面 既 “IV”
  • 5 ~ 8 就是用 一个 罗马数字 “V” 加上 0 ~ 3 个 罗马数字 “I” 来表示
  • 9 就是 10 - 1 但是减数放在了前面 既 “IX”
如果我们把每一位数字分为两组 再去发现规律:
01234
IIIIIIIV
56789
VVIVIIVIIIIX
当 0 ~ 9 我们分别对5取余时,我们发现了更通用的一个规律:
  • 余 0 ~ 3 的时候是:(“空” 或者 “V” ) 加上 余数个“I”

  • 余 4 的时候是:“I” 加上一个 “X”

由此,我们确定了罗马数字的规律,一个十进制整数的每一位,都涉及到了三个罗马数字,并按照上述的逻辑去连接罗马数字即可:

如:个位就是 I V X 三个罗马数字,十位就是 X L D 三个罗马数字, 以此类推。到目前为止我们已经发现了具体规律,我们来尝试着编写代码:

/** * @param {number} num * @return {string} */var intToRoman = function(num) {    let result = []    let unit = ['I', 'V', 'X', 'L', 'C', 'D', 'M']        let index = 0    while(num){        let n = num % 10        let pre = n >= 5 ? unit[index + 1] : ''         let u1 = unit[index]        let u3 = unit[index + ((n >= 5) ? 2 : 1)] || ''        switch (n % 5) {            case 1:                pre += u1                break            case 2:                pre += u1 + u1                break            case 3:                pre += u1 + u1 + u1                break            case 4:                pre = u1 + u3                break        }        result.push(pre)        index += 2        num = Math.floor(num / 10)    }    return result.reverse().join('')};

这道题目的具体代码实现比较简单,我这里就不逐行注释了,有一个细节需要说明,就是我在处理每一位的时候是用的push()来存入结果数字,在返回答案是先reverse(),在进行数组元素连接成字符串。

原因就是对于同样的结果操作,push() + reverse() 的操作 比 unshift() 操作快一些,这应该是js的引擎实现决定的,有更深入了解的同学欢迎留言去解释一下~。

在leetcode上,为了更快的运行结果,还可以用一些预先计算并直接体现在代码上,因为本题的要求是罗马数字在1 ~ 3999的范围,所以罗马数字组合只有四种,可以直接列出来。我们看一下leetcode上这道题目前最快的代码示例:

/** * @param {number} num * @return {string} */var intToRoman = function(num) {    function TurnFive(n, one, five, ten){        if(n != 0){            if(n < 4){                return one.repeat(n);            }            if(n == 4){                return one + five;            }            if(n < 9){                let times = n-5;                let I = one.repeat(times)                return five + I;            }            if(n == 9){                return one + ten;            }                    }        return "";    }    let than = Math.floor(num / 1000);    let hon = Math.floor(num % 1000 / 100);    let ten = Math.floor(num % 1000 % 100 /10);    let ge = Math.floor(num % 1000 %100 % 10);    return TurnFive(than, "M", "", "") +             TurnFive(hon, "C", "D", "M") +             TurnFive(ten, "X", "L", "C") +             TurnFive(ge, "I", "V", "X");};

这种针对具体题目的优化在一些online judge的比赛中很常见,不过它的扩展性就会弱一些, 比如 范围要求是 1 ~3999999 那需要在代码中直接列出来的内容就有点多了。所以还是发现规律,写出更通用的代码才是我们追求的。

这道题到这里就结束了,大家可以自己练练手,最后祝大家周末愉快,明天我会做一个《动态规划解题的常见题集合》,不过只有一道题会从头开始分析,剩下的题目只讲解思路和特征,也算是给大家留一个联系的机会,让大家真是的练练手。

如果你觉得文章的内容能给你带来收获,欢迎关注 + 点赞在看 + 转发,更期待你能推荐给身边的小伙伴,让我们一起来梳理前端知识!一起加油!「 往期回顾 」

动态规划(DP)解积雨问题

动态规划(DP)解最大连续子序列

4dfba5d518373f711b2e346677851bdd.png

文章涉及到源码已经在github中开源

请在公众号中发送“源码”获取代码地址

让我知道你在看

a7dd662c60e9063684a227ad68aeaf7c.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET MVC的路由

好久没写博文了&#xff0c;感觉最近好像少了点动力。唉&#xff01;这回就看看这个MVC的路由。 说这个路由机制其实不是MVC里面特有的&#xff0c;ASP.NET里面本身就有的&#xff0c;只不过在WebForm里面一般比较少用&#xff0c;而在MVC里就是把原本的路由扩展了。原本对不知…

java情书_Java情书已写好,就差妹子了!

我是Java程序员我用我的方式表达对你的爱&#xff01;我能抽象出整个世界...但是我却不能抽象出你...你肯定是一个单例&#xff0c;因为你是那样的独一无二...所以我的世界并不完整...我可以重载甚至覆盖这个世界里的任何一种方法...但是却不能覆盖对你的思念...也许命中注定了…

windows下手动配置ipv6地址

在XP,2003等早期版本中&#xff0c;ipv6地址在“网络连接”的属性配置里是无法手工配置的&#xff0c;只能使用netsh配置。配置方法如下&#xff1a;首先&#xff0c;安装IPV6协议&#xff0c;ipv6 install 第二步&#xff0c;查看当前使用的本地连接信息&#xff1a; 如上图&a…

java 幽灵引用_Java 幽灵引用的作用

原标题&#xff1a;Java 幽灵引用的作用来源&#xff1a;imzoer&#xff0c;blog.csdn.net/imzoer/article/details/8044900找实习的时候&#xff0c;面试大摩&#xff0c;就遇到了这个问题&#xff0c;当时真不该跟面试官交流这个内容的。垃圾收集过程中&#xff0c;对象的可触…

java assembly 打包_maven 使用assembly 进行打包的方法

1. pom 中添加assembly 插件要使用assembly 进项编译打包&#xff0c; 首先主要在pom 中的build中添加插件信息&#xff0c; 具体如图下所示&#xff1a;${project.artifactId}src/main/javasrc/main/resourcestrue**/*.xml**/*.properties${profile.dir}trueorg.apache.maven.…

rt5350 中断初始化

linux 下的中断初始化&#xff0c;实际就是对 irq_desc 这个结构体进行初始化&#xff0c;其中最关键莫过于 irq_flow_handler_t handle_irq 中断处理函数 struct irqaction *action 用户自己设置的处理函数链表&#xff0c;由hand…

VS2010安装异常中断后无法安装的解决方法(安装时发生严重错误)

最近&#xff0c;因为公司开发的需要&#xff0c;对开发环境进行全面的升级&#xff0c;在这其中也遇到了不少问题&#xff0c;在之后将陆续整理出来&#xff0c;以便以后查看。 之前开发环境&#xff1a;ArcGIS9.3&#xff0c;ArcEngine9.3&#xff0c;Oracle10g&#xff0c;A…

将5350 i2c clk设置为gpio 中断模式的方法

5350和我之前用的三星和全志的芯片在中断这块有点差别&#xff0c;三星和全志的都是有专门的外部中断管脚&#xff0c;并且每个中断管脚对应一个中断号&#xff0c;对管脚寄存器的配置即irq_desc里chip变量&#xff0c;都是bsp里自带的&#xff0c;我们只需要用request_irq来注…

代码大全 MSIL语言程序设计

.NET平台的编译器会将高级语言(C#,VB.NET,F#)编译成MSIL(微软中间语言)格式。熟悉MSIL语言&#xff0c;可以读懂一些加密程序混淆过的算法&#xff0c;这些算法几乎不能还原成高级语言&#xff0c;但是可以还原成MSIL语言。也可以知道一些高级语言之外的关于CLR的特性&#xff…

以太网交换机

以太网交换机是基于以太网传输数据的交换机&#xff0c;以太网采用共享总线型传输媒体方式的局域网。以太网交换机的结构是每个端口都直接与主机相连&#xff0c;并且一般都工作在全双工方式。交换机能同时连通许多对端口&#xff0c;使每一对相互通信的主机都能像独占通信媒体…

待办事项桌面插件_让浏览器重获整洁——标签页管理插件:OneTabOneTab PlusToby...

1 什么是标签页管理插件chrome浏览器虽然为用户提供了一个非常方便的打开新标签页的方法&#xff0c;但是随着用户浏览网页的时间增长&#xff0c;用户在一个chrome窗口中打开的标签页会越来越多&#xff0c;当这些标签页过多的时候&#xff0c;用户在标签页之间进行切换就会变…

关机时无人照管更新正在运行_了解iOS13.1后,在决定更新

苹果提前发布了首个重要更新的iOS 13.1&#xff0c;补充了多个 iOS 13 首发时缺失的重要新功能&#xff0c;可以说 iOS 13.1 才是【真正】的 iOS 13 系统。苹果发布iOS13.1,都更新了哪些内容&#xff1f;iOS13.1修复问题和改进问题&#xff1a;?信息中拟我表情可能无法正确跟踪…

山西计算机网络技术专升本分数线_2020山西成考专升本招生补录第一批公告!附补录院校专业缺额表!...

☞回复【成绩】查询2020年成人高考成绩☞回复【录取】查询20成考录取结果☞回复【补录】查询最新院校缺额信息☞加入学历备考交流群 550985358 专升本第一阶段补录通知与院校缺额信息 达线未被录取&#xff1f;还有机会2020山西成考专升本招生征集志愿第一阶段公告发布12月9日1…

网页编码就是那点事

编码一直是让新手头疼的问题&#xff0c;特别是 GBK、GB2312、UTF-8 这三个比较常见的网页编码的区别&#xff0c;更是让许多新手晕头转向&#xff0c;怎么解释也解释不清楚。但是编码又是那么重要&#xff0c;特别在网页这一块。如果你打出来的不是乱码&#xff0c;而网页中出…

Linux C 中字符串化操作符#

1 #include <stdio.h>2 3 #define dprint( expr ) printf( "%s %d \n", #expr , expr)4 5 int main(void)6 {7 int x 100;8 int y 2;9 10 dprint(x/y); 11 dprint( xy ); 12 dprint( xy2 ); 13 return 0; 14 } 打印信息&…

U-BOOT之一:BootLoader 的概念与功能

U-BOOT之一&#xff1a;BootLoader 的概念与功能 ——转自《U-BOOT移植S3C2440完全手册》 1.1嵌入式Linux 软件结构与分布 一般情况下嵌入式Linux 系统中的软件主要分为以下几部分&#xff1a; 1) 引导加载程序&#xff1a;其中包括内部ROM 中的固化启动代码和BootLoader 两部分…

java写七彩文字_【PS精选案例教程】创建一个漂亮的七彩文字

原标题&#xff1a;【PS精选案例教程】创建一个漂亮的七彩文字效果图&#xff1a;步骤1. 新建一个文档(大小随意)步骤2. 滤镜→渲染→云彩步骤3. 可以按CtrlAltF增加效果步骤4. CtrlJ复制一层步骤5.设置前景色步骤6. 用径向渐变从中间往外拉一个渐变步骤7. 设置“图层1”混合模…

容斥原理的二进制实现模版

最近学习容斥原理&#xff0c;实现容斥原理大致有三种方法&#xff1a;dfs&#xff0c;队列数组&#xff0c;二进制。 今天主要讲下二进制实现容斥原理&#xff1a; 有一个集合{A1……An}&#xff0c;求集合的子集&#xff1f;很显然答案为 也就是2^n个&#xff0c;也就是每一个…

测试鼠标双击_鼠标环境可靠性测试是什么

鼠标和电脑是的组合&#xff0c;购买电脑时一般商家会送给用户一个配套的鼠标&#xff0c;鼠标和电脑一样&#xff0c;对环境的要求较高&#xff0c;极少部分的鼠标由于短路或者是环境温度过高的问题会导致鼠标出现自燃的现象&#xff0c;如果用户此时正在使用电脑编辑文件&…

virtualbox主机网络管理 未能创建_如何在 VirtualBox 中增加现有虚拟机的磁盘大小 | Linux 中国...

导读&#xff1a;你可以在 VirtualBox 中扩大虚拟硬盘&#xff0c;即使在创建之后也可以。                   本文字数&#xff1a;1434&#xff0c;阅读时长大约&#xff1a;2分钟https://linux.cn/article-12869-1.html作者&#xff1a;Dimitrios Savvopoulos译者…