LeetCode题目笔记--12.整数转罗马数字

2023-11-17

题目描述

  题目跟前面13题描述一样,就是问题变为整数转成罗马数字。

思路

  上一道题罗马数字转整数比较简单,因为不存在罗马数字表示冲突的问题,即不存在一个罗马数字对应多个整数。而这个问题中,就要考虑一下这个问题了,因为如果不加以约束的话,一个整数可以用多种罗马数字来表示。比如对于2000:

2000 = 1000 + 1000 = M + M,即MM
2000 = 1000 + 900 + 100 = M + CM + C,即MCMC

  于是,我特地查了一下,罗马数字的排列规则是从左到右尽可能用最大的数字来表示。那么,就像之前那样,准备好一个字典,反过来以整数为键,罗马数字为值,存放13种键-值组合。
  然后,只要整数num(待转换的数)不为0,就在每次循环里找到一个离他最近的罗马数字对应的整数n,记录该罗马数字,然后让num-n,继续循环,直到num=0为止。
伪代码描述:

buf = {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 = “”
while num != 0
  找到最接近num的整数n
  res += buf[n]
  num -= n
return res

python代码(low版)

class Solution:
    def intToRoman(self, num: int) -> str:
        buf = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 
                500:'D', 1000:'M', 4:'IV', 9:'IX',
                40:'XL', 90:'XC', 400:'CD', 900:'CM'}
        d_keys = list(buf.keys())
        d_keys.sort(reverse = True)
        if num in d_keys:
            return buf[num]
        res = ''
        t = 0
        while num != 0:
            for n in d_keys:
                t = num - n
                if t >= 0:
                    res += buf[n]
                    num -= n
                    break

        return res

  这是第一版代码,运行时间80ms,慢得一*,观察代码,可以看见真的憨憨,创建字典时竟然乱序,后面还要排序,而且在while里每次for都是从第一个元素开始,这无疑浪费时间,从上次break的位置接着往后找他不香吗?而且再仔细想想,也没必要先判断num是否是正好对应现成的,反正in操作的原理也是循环,所以这里可以删掉。

改进一点的python代码

class Solution:
    def intToRoman(self, num: int) -> str:
        buf = {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'}
        d_keys = list(buf.keys())
        res = ''
        idx = 0
        size = d_keys.__len__()
        while num != 0:
            for i in range(idx, size):
                t = num - d_keys[i]
                if t >= 0:
                    res += buf[d_keys[i]]
                    num -= d_keys[i]
                    break
            idx = i

        return res

提交,运行时间64ms,还是有点慢,无奈去看了看官方题解,原来我前面的思路是贪心算法的思路,这我还真没想到。

最终代码

  官方题解的代码给了我灵感,原来可以这样写:

class Solution:
    def intToRoman(self, num: int) -> str:
        buf = {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 n in buf.keys():
            if num == 0:
                break

            quotient, num = divmod(num, n)
            res += buf[n] * quotient
        return res

  这样写的好处就在于一遍循环就能解决问题,那58来说,前面的代码在执行到num = 3时,会做3次for循环,而这3次循环都都几乎是同样的操作,效率极低,而这里用到的字符串“乘法”操作,在这种情况下就极大的提高效率,真香!

C++实现

class Solution {
public:
    string intToRoman(int num) {
        string res;
        /*map <int, string, greater<int>> dict = {{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"}};
        for(auto &t : dict)
        {
            if(num == 0)
            {
                break;
            }
            while(num >= t.first)
            {
                num -= t.first;
                res += dict[t.first];
            }
        }*/
        //更快的解法
        int key[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        string values[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        for(int i = 0; i < 13; i++)
        {
            if(num == 0)
            {
                break;
            }
            while(num >= key[i])
            {
                num -= key[i];
                res += values[i];
            }
        }
        return res;
    }
};

  注释掉的地方是用的map,运行时间32ms,只比python快了20ms,也许是创建map比较耗时的原因吧,我觉得还能更快,所以把键值对拆开成两个数组,这样下来运行时间是12ms。
  还有就是,就算给map的初值是按顺序写的,但map内部实现还是无序,因此还要在map的类型说明里加上greater参数,指明按int(这里就是键)降序排序。我第一次没加这个参数,结果答案全是“IIIIIIII…”,看了其他大佬的博客才明白,学到了学到了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode题目笔记--12.整数转罗马数字 的相关文章

随机推荐

  • matlab figure函数的用法

    https blog csdn net qq 30387863 article details 80301996
  • (三) 区块链数据结构 – 交易

    区块由交易组成 区块体中包含若干项交易数据 交易 交易主要包含两类数据 交易输入和交易输出 交易输入用来指明钱的来源 交易输出用来指明钱的去向 除了交易输入和交易输出外 交易中还包含版本号和锁定时间 交易数据的存储结构如下 交易对象中的各个
  • Flink State 和 Fault Tolerance详解

    有状态操作或者操作算子在处理DataStream的元素或者事件的时候需要存储计算的中间状态 这就使得状态在整个Flink的精细化计算中有着非常重要的地位 记录数据从某一个过去时间点到当前时间的状态信息 以每分钟 小时 天汇总事件时 状态将保
  • 平面离散点集Delaunay三角化

    文章目录 定义 准则 特性 算法 1 逐点插入法 2 分治算法 3 生长算法 对比 参考 定义 在数学和计算几何中 三角化就是对于给定的平面中的离散点集P 生成三角形集合T的过程 一般来说给定一个点集 往往存在不止一个三角剖分 其中基于 D
  • 大数据时代下对NoSQL数据库的理解

    Web 2 0时代的到来 关系数据库越来越不能满足互联网应用的需求 导致了NoSQL的兴起 NoSQL数据库在大数据领域里越来越受欢迎 数据的高并发读写 数据的高可用性 海量数据存储 海量数据的实时分析 文档型数据库 代表 MongoDB
  • 边缘计算在物联网领域的研究与分析

    本文首发于 5G工业互联 作者黄泽龙 摘 要 物联网的发展开启了万物互联时代 设备的爆炸式增长和应用的多样化带来了海量数据 对传输带宽 时效性 异构接入等提出了新要求 边缘计算在靠近数据源侧进行数据处理 有效地减少数据传输量 降低服务响应时
  • c++虚函数实现机制及内存模型

    前言 大家都应该知道C 的精髓是虚函数吧 虚函数带来的好处就是 可以定义一个基类的指针 其指向一个继承类 当通过基类的指针去调用函数时 可以在运行时决定该调用基类的函数还是继承类的函数 虚函数是实现多态 动态绑定 接口函数的基础 可以说 没
  • 深度强化学习系列: “奖励函数”的设计和设置(reward shaping)

    概述 前面已经讲了好几篇关于强化学习的概述 算法 DPG gt DDPG 也包括对环境OpenAI gym的安装 baseline算法的运行和填坑 虽然讲了这么多 算法也能够正常运行还取得不错的效果 但是一直以来忽略了一个非常重要的话题 那
  • 篇六:线性查找

    线性查找 又称顺序查找 是一种最简单的查找方法 它的基本思想是从第一个记录开始 逐个比较记录的关键字 直到和给定的K值相等 则查找成功 若比较结果与文件中n个记录的关键字都不等 则查找失败 假设一个数组arr 23 98 56 76 38
  • 检验链表是否形成环

    以下两个方法只要是存在环快慢指针就一定相遇 1 快慢指针 2 fast先走K步 从第K个节点出发 gt gt 相当于在求倒数第K个节点 除了快慢指针 可以用记录步数是否相同 来判断是否会相遇 int has loop node t head
  • A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution

    今天在编译Kotlin项目时 遇到以下错误信息 信息中没有具体指明错误原因 只是报错 A failure occurred while executing org jetbrains kotlin gradle internal KaptE
  • IP首部报文字段

    一 IP首部报文字段 字段如下图所示 二 每个字段的含义 版本 表示 IP 协议的版本 通信双方使用的 IP 协议版本必须一致 目前广泛使用的IP协议版本号为 4 即 IPv4 首部长度 这个字段所表示数的单位是 32 位字长 1 个 32
  • postgreSQL中无法更改数据的问题

    增对这个bug 参考博客 解决Navicat修改Mysql数据后刷新恢复原样的问题 无法提交事务 Studiouss的博客 CSDN博客 发现我的问题是解决了 因为我确实没有设置主键 或者是设置主键没有保存造成的 这样就解决了 点击刷新 表
  • 自动化测试面试题及答案大全(2)

    问题1 Selenium是什么 流行的版本有哪些 是一个开源的web自动化测试的框架 支持多种编程语言 支持跨浏览器平台进行测试 Selenium 1 0或Selenium RC Selenium 2 0或Selenium Webdrive
  • VisualStudio神级插件——JetBrains Resharper 2018.2.3 Ultimate完美破解版教程

    VisualStudio神级插件 JetBrains Resharper 2018 2 3 Ultimate完美破解版 教程 ReSharper是一个JetBrains公司出品的著名的代码生成工具 是Visual Studio里面的一个插件
  • 中职本科计算机大学课程设置,中职学校计算机专业课程设置问题与对策研究——以湖南省五所中职学校为例...

    摘要 随着我国市场经济的发展 产业结构和劳动力结构不断调整 因此对劳动者的素质和结构都提出了新的要求 形成了对技能型人才需求的调整增长态势 技能型人才的紧缺 结构性失业问题已成为制约我国经济增长的瓶颈 中职教育作为目前职业教育的主体 它承担
  • 文件服务器 安全,文件服务器 安全

    文件服务器 安全 内容精选 换一换 云堡垒机支持批量导出资源信息 用于本地备份资源配置 以及便于快速管理资源基本信息 为加强资源信息安全管理 支持加密导出资源信息 导出的主机资源文件中包含主机基本信息 主机下所有资源账户信息 主机资源账户明
  • linuxmake没有指明目标并且找不到makefile_Makefile笔记

    一般来说 无论是C C 还是pas 首先要把源文件编译成中间代码文件 在Windows下也就是 obj 文件 UNIX下是 o 文件 即 Object File 这个动作叫做编译 compile 然后再把大量的Object File合成执行
  • ssh 连接报错:Unable to negotiate with 192.168.xx.xx port 22: no matching key exchange method found.

    用 ssh 连接 Linux 服务器时 很偶然的情况下出现了如下报错 Unable to negotiate with xx xx xx xx port 22 no matching key exchange method found Th
  • LeetCode题目笔记--12.整数转罗马数字

    题目描述 题目跟前面13题描述一样 就是问题变为整数转成罗马数字 思路 上一道题罗马数字转整数比较简单 因为不存在罗马数字表示冲突的问题 即不存在一个罗马数字对应多个整数 而这个问题中 就要考虑一下这个问题了 因为如果不加以约束的话 一个整