深入探索力扣第12题:整数转罗马数字的算法之旅

力扣(LeetCode)第12题“整数转罗马数字”提供了一个绝佳的学习机会,不仅让我们深入古罗马的数字系统,也锻炼了我们的编程技巧。一起看看其背后的逻辑。

罗马数字基础

罗马数字是一种古老的数字表示方法,广泛用于古罗马时期。不同于现代的十进制数字系统,罗马数字使用字母来表示不同的数值。以下是罗马数字的基本组成部分:

  • 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。

问题描述

力扣第12题要求我们将给定的整数转换为罗马数字表示,该整数范围从1到3999。这个范围的限定是由罗马数字表示的上限所决定的。

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

算法思路

要有效地解决这个问题,我们可以采用“贪心算法”来逐步构建罗马数字表示。贪心算法是一种在当前步骤中选取最优解的算法,以此希望整体达到最佳解的策略。

解题步骤

  1. 准备映射表:首先,创建一个映射表,列出所有单一罗马数字及其值,以及特殊的减法规则组合(如IV表示4)。
  2. 逐步减少:从最大的数值和对应的罗马数字开始,尽可能多地从输入整数中减去该数值,每次减去时,将相应的罗马数字添加到结果字符串中。
  3. 重复直到完成:继续此过程,直到整数减少到0。

代码实现(Python)

def intToRoman(num: int) -> str:roman_map = [
(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")
]roman_numeral = ""for value, symbol in roman_map:while num >= value:num -= valueroman_numeral += symbol
return roman_numeral

性能分析

对于该算法,其时间和空间复杂度都可以认为是O(1),因为罗马数字表示的整数有一个上限(3999),算法运行时间和所需空间并不随输入整数的大小而变化。

算法图解

动态GIF图

为了将上述绘图过程转换成动态GIF图片,我们需要在Python中采用稍微不同的方法。这通常涉及到在每个绘图步骤中保存图像,并最后使用这些图像来创建GIF。下面是一个如何实现这一过程的示例:

  1. 保存每一步的图像:在循环中,每执行一次操作(即每次从数字中减去一个罗马数字值),我们都将保存当前的图表状态作为一个图像文件。
  2. 创建GIF:使用这些图像文件创建GIF。我们可以使用像imageio这样的库来完成这个任务。

bb425c7b1df14e7385349539ee093b38.gif

代码实现(Python)

首先,确保你已经安装了imageio库。如果还没有安装,你可以通过运行pip install imageio来安装它。

接下来,让我们更新代码来实现这个过程:

 

import matplotlib.pyplot as plt
import imageio
import os# 定义罗马数字映射和待转换的数字
numerals = [(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')
]
num = 1994
original_num = num# 准备存放每一帧图像的目录
frames_dir = "frames_dir"
os.makedirs(frames_dir, exist_ok=True)filenames = []  # 存储每一帧图像文件名# 转换过程
result = ""  # 累积的罗马数字
for value, symbol in numerals:while num >= value:num -= valueresult += symbol# 绘图fig, ax = plt.subplots(figsize=(10, 6))ax.text(0.5, 0.7, f'Converting: {original_num} to Roman Numerals', ha='center', va='center', fontsize=14)ax.text(0.5, 0.5, f'- {symbol} ({value})', ha='center', va='center', fontsize=20, color='red')ax.text(0.5, 0.4, f'Remaining: {num}', ha='center', va='center', fontsize=14)ax.text(0.5, 0.6, f'Converted: {result}', ha='center', va='center', fontsize=14)ax.axis('off')# 保存图像filename = os.path.join(frames_dir, f'frame_{original_num - num}.png')plt.savefig(filename)plt.close()filenames.append(filename)# 生成GIF
gif_filename = 'roman_conversion.gif'
with imageio.get_writer(gif_filename, mode='I', duration=0.5) as writer:for filename in filenames:image = imageio.imread(filename)writer.append_data(image)# 清理临时文件
for filename in filenames:os.remove(filename)
os.rmdir(frames_dir)print(f"GIF saved as {gif_filename}")

执行步骤解析

  1. 初始化和映射定义:设置罗马数字映射和待转换的数字。
  2. 创建帧目录:为每一步生成的图像帧创建一个存放目录。
  3. 绘图和保存:对每个罗马数字减法操作,绘制并保存一帧图像。
  4. GIF生成:使用imageio读取所有帧图像并合成GIF。
  5. 清理:删除所有临时帧图像和目录。

结论

通过动态的GIF图示我们更好的掌握算法的运行步骤

 

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

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

相关文章

YOLOv9改进策略 :小目标 | 新颖的多尺度前馈网络(MSFN) | 2024年4月最新成果

💡💡💡本文独家改进:多尺度前馈网络(MSFN),通过提取不同尺度的特征来增强特征提取能力,2024年最新的改进思路 💡💡💡创新点:多尺度前馈网络创新十足,抢先使用 💡💡💡如何跟YOLOv8结合:1)放在backbone后增强对全局和局部特征的提取能力;2)放在detect…

尚硅谷html5+css3(1)html相关知识

1.基本标签&#xff1a; <h1>最大的标题字号 <h2>二号标题字号 <p>换行 2.根标签<html> 包括<head>和<body> <html><head><title>title</title><body>body</body></head> </html> 3…

SpringBoot学习之Kibana下载安装和启动(Mac版)(三十二)

一、简介 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。 …

C语言单链表

1. 单链表的概念和结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。 链表与顺序表都属于线性表&#xff0c;顺序表在物理存储结构上是线性的&#xff0c;但是链表在物理存储结构上…

P1123 取数游戏(dfs算法)

题目描述 一个 NM 的由非负整数构成的数字矩阵&#xff0c;你需要在其中取出若干个数字&#xff0c;使得取出的任意两个数字不相邻&#xff08;若一个数字在另外一个数字相邻 8个格子中的一个即认为这两个数字相邻&#xff09;&#xff0c;求取出数字和最大是多少。 输入格式 第…

蝙蝠优化算法(bat optimization algorithm)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 蝙蝠优化算法&#xff08;Bat Algorithm&#xff09;是一种基于群体智能的优化算法&#xff0c;它的灵感来源于蝙蝠捕食时的回声定位行…

Python3 replace()函数使用详解:字符串的艺术转换

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

[从0开始AIGC][Transformer相关]:算法的时间和空间复杂度

一、算法的时间和空间复杂度 文章目录 一、算法的时间和空间复杂度1、时间复杂度2、空间复杂度 二、Transformer的时间复杂度分析1、 self-attention 的时间复杂度2、 多头注意力机制的时间复杂度 三、transformer的空间复杂度 算法是指用来操作数据、解决程序问题的一组方法。…

人工智能应用工程师特训营丨国家认证,行业必备

人工智能应用工程特训营 提升目标&#xff1a; 1、提高专业认可度&#xff0c;增强职场竞争力 2、实战项目驱动&#xff0c;提升应用能力 3、技术体系全面&#xff0c;涵盖多个领域 4、实时在线答疑&#xff0c;强化学习互动 特训营学习流程&#xff1a; 职业技术证书&#xff…

【鸿蒙开发】系统组件Text,Span

Text组件 Text显示一段文本 接口&#xff1a; Text(content?: string | Resource) 参数&#xff1a; 参数名 参数类型 必填 参数描述 content string | Resource 否 文本内容。包含子组件Span时不生效&#xff0c;显示Span内容&#xff0c;并且此时text组件的样式不…

数学基础:常见函数图像

来自&#xff1a; https://www.desmos.com/calculator/l3u8133jwj?langzh-CN 推荐: https://www.shuxuele.com/index.html 一、三角函数 1.1 正弦 sin(x) 1.2 余弦 cos(x) 1.3 正切 tan(x) 1.4 余切 cot(x) 1.5 正弦余弦综合 1.6 正切余切综合 二、指数对数

Linux内核自带的LED驱动实验:Led驱动功能测试

一. 简介 前面几篇文章学习了如何使用Linux内核自带的Led驱动。一篇文章通过对驱动分析&#xff0c;了解了驱动与设备匹配的关键点。 一篇文章学习了如何配置使能Linux内核自带的Led驱动&#xff0c;第二篇文章学习创建Led设备树节点&#xff08;针对使用Linux内核自带的Led…

HJ37 统计每个月兔子的总数(动态规划)

高端的食材&#xff0c;往往只需要最简单的烹饪方法。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的…

小米汽车:搅动市场的鲶鱼or价格战砧板上的鱼肉?

3月28日晚&#xff0c;备受关注的小米汽车上市发布会召开&#xff0c;小米集团董事长雷军宣布小米SU7正式发布。小米汽车在带飞股价的同时&#xff0c;二轮订购迅速售尽。 图一&#xff1a;小米集团股价 雷军口中“小米汽车迈出的第一步&#xff0c;也是人生最后一战的开篇”&a…

Spring Cloud微服务入门(五)

Sentinel的安装与使用 安装部署Sentinel 下载Sentinel&#xff1a; https://github.com/alibaba/Sentinel/releases Sentinel控制台 https://localhost:8080 用户和密码为sentinel 使用Sentinel 加依赖&#xff1a; 写配置&#xff1a; 输入&#xff1a; java -Dserver.po…

《QT实用小工具·二十二》多种样式导航按钮控件

1、概述 源码放在文章末尾 该项目实现了多种样式的导航按钮控件 可设置文字的左侧、右侧、顶部、底部间隔。 可设置文字对齐方式。 可设置显示倒三角、倒三角边长、倒三角位置、倒三角颜色。 可设置显示图标、图标间隔、图标尺寸、正常状态图标、悬停状态图标、选中状态图标…

基于spring boot的漫画之家系统

基于spring boot的漫画之家系统设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&…

程序语言基础

根据希赛相关视频课程汇总整理而成&#xff0c;个人笔记&#xff0c;仅供参考。考点偏向于通用程序语言的基础概念。 程序语言基础概念 程序设计语言&#xff1a; ①低级语言 机器语言汇编语言 汇编语言&#xff1a;指令语句/伪指令语句/宏指令语句 ②高级语言 Fotrane语言&…

vscode连接远程服务器一直需要输密码,但是连不上

问题&#xff1a;vscode连接远程服务器一直需要输密码&#xff0c;但是连不上。 解决办法&#xff1a;kill 掉该远程服务器&#xff0c;然后再重新连接 操作&#xff1a; windows: ctrlshiftp mac:cmdshiftp 调出指令&#xff0c;然后选择“Remote SSH:Kill Vscode Serve…

强化学习MPC——(二)

本篇主要介绍马尔科夫决策&#xff08;MDP&#xff09;过程&#xff0c;在介绍MDP之前&#xff0c;还需要对MP&#xff0c;MRP过程进行分析。 什么是马尔科夫&#xff0c;说白了就是带遗忘性质&#xff0c;下一个状态S_t1仅与当前状态有关&#xff0c;而与之前的状态无关。 为…