题目在leetcode上的链接为:
https://leetcode-cn.com/problems/integer-to-roman/
题目描述
解题思路
由于整数与罗马数字存在一种映射关系,所以我们可以建立哈希表来表示这种映射关系,哈希表中的 key 为整数,value 为对应的罗马数字(字符串)。我们将题目中的7种单个字符以及6种两个字符的特殊情况一共13种映射情况,按照对应的整数从大到小的顺序建立哈希表(python 中使用 dict 进行哈希表):
dic = {1000 : "M", 900 : "CM", 500 : "D", 400 : "CD", 100 : "C",
90 : "XC", 50 : "L", 40 : "XL", 10 : "X",
9 : "IX", 5 : "V", 4 : "IV", 1: "I"}
然后循环遍历一遍哈希表中的 key,每一步中使用整数 num//key 就得到了这个 key 对应的罗马字符的数目,只有当这个数目大于0时才需要转换为对应的罗马数字(数目等于0则不用处理),然后 num%key 就得到剩余的未转换的数字,这样循环结束后就得到了转换后的罗马数字。
例如对于示例5中 num=1994,转换成罗马数字的步骤为:
初始化转换后的罗马数字(字符串)为 res=""
遍历 dic 中的 key
(1)首先 key=1000,num//key=1994//1000=1,此时res+=dic[1000]*1=“M”,则此时 res=“M”,剩余的数字为 num=num%key=1994%1000=994,
(2)然后 key=900,num//key=994//900=1,此时res+=dic[900]*1=“CM”,则此时 res=“MCM”,剩余的数字为 num=num%key=994%900=94,
(3)然后 key=500,num//key=94//500=0,此时不需要进行任何操作,一直遍历下去直到 key=90时,num=num//key=94//90=1,此时res+=dic[90]*1=“XC”,则此时 res=“MCMXC”,剩余的数字为 num%key=94%90=4,
(4)然后 key=50,num//key=4//50=0,此时不需要进行任何操作,一直遍历下去直到 key=4时,num//key=4//4=1,此时res+=dic[4]*1=“IV”,则此时 res=“MCMXCIV”,剩余的数字为 num=num%key=4%4=0,然后直到遍历结束,num//key=0//key=0,不需要进行任何操作。
因此得到的1994转化为的罗马数字为 res=“MCMXCIV”
复杂度分析:
由于只需要遍历一遍哈希表的 key,而 key 的个数为常数个,因此时间复杂度为 o(1)
由于需要建立一个哈希表储存常数个整数到字符串的映射,因此空间复杂度为 o(1)
python代码:
class Solution:
def intToRoman(self, num):
dic = {1000 : "M", 900 : "CM", 500 : "D", 400 : "CD", 100 : "C",
90 : "XC", 50 : "L", 40 : "XL", 10 : "X",
9 : "IX", 5 : "V", 4 : "IV", 1: "I"}
res = ""
for key in dic:
count = num // key
if count != 0:
res += dic[key] * count
num %= key
return res