题目描述

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值

I 1

V 5

X 10

L 50

C 100

D 500

M 1000

例如, 罗马数字 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 的范围内。

解题思路

由题意可知,从整数转化为罗马数字的时候,每个位上的数字(0~9)都是由四种类型的罗马数字组成的

比如个位数:

'(null)'

I

V

X

通过此思路,我们可以构造一个二维list。

self.Glossary = [

['I','V','X'],

['X','L','C'],

['C','D','M'],

['M'],

]

傲娇脸(感觉这种思路更深一点)

相比其他巨佬(我是菜鸡)的题解中构造的数组,比如@liweiwei1419的题解:

nums = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]

romans = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]

这种思路相当于是将每个位数(比如个位数)的1-4-5-9给单独列出来了。其中1 5 10 是构造数字的单元(最底层)的单元字符,而因为4和9的构造规则和123 678的规则不一样,所以题主将1-4-5-9单独列出来再进行算法匹配,就更顺畅。这位巨佬的每个位数需要构造4个字符,但是上述的构造方法只需要定义三个单元字符。

m = [

['', 'M', 'MM', 'MMM'],

['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'],

['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],

['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']

]

可能大家看到这种的时候会想,这么直接的吗,把每个位数的1-9全部列出来了,但是我感觉这种方法相比上面第一个巨佬的方法更好一些,因为这种方法的思路比较清晰:我分位数来构造数组,将每个位的所有出现的情况全部列出来,这种方式就相当于我们先花最大的空间来构造我们需要的(类似哈希表吧),然后再用复杂度比较低的算法来进行简单的匹配。

class Solution:

def intToRoman(self, num):

m = [

['', 'M', 'MM', 'MMM'],

['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'],

['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],

['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']

]

d = [1000, 100, 10, 1]

r = ''

for k, v in enumerate(d):

r += m[k][int(num/v)]

num = num % v

return r

妙啊,点个赞。(这种思路将算法最简单化,但是空间的使用也是最大的)

好了,上述引用的两个大佬,我真的觉得很牛逼,将空间略微复杂化了然后使用最巧妙地算法。

那使用这种最底层地单元化地构造方法:

self.Glossary = [

['I','V','X'],

['X','L','C'],

['C','D','M'],

['M'],

]

如何来写算法呢

罗马数字地构造思路:

在每一个(十分)位上

用1单元位来叠加构造1-3 比如I,II,III 或者X,XX,XXX

用1和5单元位来构造4 比如IV 或者XL

用5来直接使用 比如V 或者L

用1和5来构造6-8 比如VI,VII,VIII或者LX,LXX,LXXX

用1和10来构造9 比如IX 或者XC

说到这里其实,罗马数字是一种5进制地数,(个人认为哈)。

但是由于我们地整数时10进制地,所以4和9地构造相当于就是两种不同地构造方法(用此十分位的1和5来构造、用此此十分位的1和下个十分位的10来构造)

那我们需要将这几个特例拿出来:

while _

res+=v[0]

_+=1

if _==4:

res=v[0]+v[1]

elif _==5:

res=v[1]

elif _==9:

res=v[0]+v[2]

具体代码如下:

def viaDict(self, num:int) -> str:

resl,nlist=[],list(str(num))

for k,v in enumerate(self.Glossary):

try:

_,res,x=0,'',int(nlist.pop())

while _

res+=v[0]

_+=1

if _==4:

res=v[0]+v[1]

elif _==5:

res=v[1]

elif _==9:

res=v[0]+v[2]

resl.insert(0,res)

except (StopIteration,IndexError):

# 遇到StopIteration就退出循环

break

return "".join(resl)

代码

#

# @lc app=leetcode.cn id=12 lang=python3

#

# [12] 整数转罗马数字

#

# @lc code=start

class Solution:

def __init__(self):

self.Glossary = [

['I','V','X'],

['X','L','C'],

['C','D','M'],

['M'],

]

def viaDict(self, num:int) -> str:

resl=[]

# get the Iterator Object first:

nlist = list(str(num))

for k,v in enumerate(self.Glossary):

try:

_=0

res=''

x=int(nlist.pop())

while _

res+=v[0]

_+=1

if _==4:

res=v[0]+v[1]

elif _==5:

res=v[1]

elif _==9:

res=v[0]+v[2]

resl.insert(0,res)

except (StopIteration,IndexError):

# 遇到StopIteration就退出循环

break

return "".join(resl)

def intToRoman(self, num: int) -> str:

return {

1:lambda num:self.viaDict(num),

}[1](num)

# @lc code=end

if __name__ == "__main__":

solve = Solution()

# print(solve.Glossary.items())

print(solve.intToRoman(444))

一百个人读哈姆雷特就有一百个哈姆雷特。

leetcode

leetcode解题得的源码,解题思路在代码的注释里。

本作品采用《CC 协议》,转载必须注明作者和本文链接

python编程比赛初赛 组成最小罗马数字_leetcode 题解 12python3@ 通过使用罗马数字的最单元位来构造数组 + 构造数字算法...相关推荐

  1. python编程比赛初赛 组成最小罗马数字_Python每日一编程小练习(2019.06.13)——罗马数转换为整数...

    题目: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符          数值 I             1 V             5 X             1 ...

  2. python编程比赛_用Python编程分析4W场球赛后,2018世界杯冠军竟是…

    比赛已经开始,我们不妨用 Python 来对参赛队伍的实力情况进行分析,并大胆的预测下本届世界杯的夺冠热门球队吧! 通过数据分析,可以发现很多有趣的结果,比如: 找出哪些队伍是首次进入世界杯的黑马队伍 ...

  3. 广东python编程比赛

    一.jieba库-分词 1 模式 精确模式,试图将句子最精确地切开,适合文本分析: 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义: 搜索引擎模式,在精确模式的基础上, ...

  4. 青少年python编程比赛试题答案_中国大学moocPython编程基础试题及答案

    参考答案如下 新时期的思想解放,中国是从( )开始的 定时\\\\/计数器若工作在循环定时或循环计数场合,大学为了能够自动完成计数初值的加载,应选用( ). 公安机关依法对违反行政法律规范的人,编程 ...

  5. 青少年电子信息智能创新大赛 -- Python编程挑战赛初赛试题说明

  6. 青少年python编程比赛试题答案_Python编程及应用-中国大学mooc-试题题目及答案

    [填空题]光电二极管广泛应用于光信号检测和光信号转换电路中,工作时应加 ( ) 偏置 电压,其反向电流随光照强度的增加而 ( ) . (3.0分) [单选题]差分放大器中,若 u I1 =2.02V ...

  7. 超级码力在线编程大赛初赛 第2场 【题解】

    三角魔法 思路 1.利用叉乘判断点是否在直线的逆时针方向 2.如果点是在三条边的逆时针方向,则点在三角形内. 3.坑点:判断三点是否形成三角形,也是利用叉乘判断. AC代码 class Solutio ...

  8. 超级码力在线编程大赛初赛 第2场 T1-T4题解

    文章目录 T3.五字回文 T2.区间异或 T1.三角魔法 T4.小栖的金字塔 T3.五字回文 class Solution {public:/*** @param s: The given strin ...

  9. 超码在线编程大赛初赛 第1场(简要题解)

    前言:赛后做了一下题目,感觉题目难度还可以. 树木规划 思路: l o w e r _ b o u n d + lower\_bound+ lower_bound+贪心即可. 正三角形拼接 思路:显然 ...

最新文章

  1. 全面解析Java的垃圾回收机制
  2. 详解vue的diff算法
  3. 接口应用小玩具-博客园积分排名变动监控工具
  4. Filter案例之敏感词过滤和代理模式
  5. SpringMVC整合Shiro
  6. lfu算法实现c语言_哈希查找算法(C语言实现)
  7. 一行一个链接代码_小白写代码讨女朋友欢心,包教包会
  8. 表达式计算引擎-JEP
  9. 程序员的编辑器 notepad++ || XML编辑器
  10. 新手自己搭建服务器步骤
  11. 8个免费图片素材网,赶紧收藏起来
  12. Appscan漏洞之Authentication Bypass Using HTTP Verb Tampering
  13. 中国撸串指北:13万家烧烤店的吃货最爱
  14. 微信小游戏获取排行榜
  15. 有序的uuid(32位)
  16. 2.3 万 Star!直追微软 Visio,这个简洁实用的在线绘图工具必须推荐给你
  17. 中科院正研制多核CPU龙芯3号 将用于超级计算机(转)
  18. oracle+cascade=gt;true,mysql数据库主外键级联删除脚本RESTRICT -- CASCADE
  19. 大分享-hibernate,springmvc,easyui简要介绍
  20. 【渝粤教育】广东开放大学 互换性原理 形成性考核 (29)

热门文章

  1. Axure手机移动端交互原型通用元件库
  2. Nginx 基本理论和安装
  3. 怎么用鸿蒙os系统,鸿蒙OS2.0系统怎么降级到EMUI11 鸿蒙OS2.0系统降级到EMUI11方法...
  4. 语法长难句-----简单句
  5. 【2022 CCF BDCI 文心大模型创意项目】乐享词话—诗词意境辅助记忆工具
  6. 新手小白用C# winform 读取Excel表
  7. 小鼠心肌细胞培养方法
  8. Linux 桌面虚拟化技术 KVM
  9. linux双系统如何选择顺序,Ubuntu和Windows双系统选择开机顺序
  10. Python数据挖掘(1)亲和性分析