【每日一题】LeetCode - 整数转罗马数字

在罗马数字系统中,七个不同的符号代表不同的值:

符号
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

罗马数字的表示方式是从最大值开始逐次减去每个符号的值,通过组合这些符号构建最终的表示形式。本文将介绍一个基于贪心策略的解决方案,将整数转换为罗马数字。

解题思路

给定一个整数,我们需要通过罗马数字表示出来。罗马数字的构建规则非常有趣:通常情况下,从较大的数值符号开始,按递减顺序逐步添加符号来表示出整个数。但当数位中以4或9开头时,采用"减法形式"表示------比如4用"IV"而不是"IIII"表示,9则用"IX"而不是"VIIII"。这里,我们需要从高位逐步匹配适合的罗马符号值,并从当前整数中减去该符号对应的数值,直到当前整数变为0。

在此代码实现中,首先定义了一个映射表,按从大到小的顺序列出整数与罗马符号的关系,这样便于直接找到合适的符号。然后,我们从最大的数值符号开始遍历,使用一个 while 循环来处理当前数值。当当前数值大于等于符号所代表的值时,减去该值并将对应的符号附加到结果字符串中。通过不断重复上述过程,我们最终得到完整的罗马数字表示。

示例

以下是几个示例解释:

  • 输入 num = 3749,输出结果为 "MMMDCCXLIX",解释如下:
    • 3000 = "MMM",因为 1000 (M) + 1000 (M) + 1000 (M)
    • 700 = "DCC",因为 500 (D) + 100 © + 100 ©
    • 40 = "XL",因为 50 (L) - 10 (X)
    • 9 = "IX",因为 10 (X) - 1 (I)
  • 输入 num = 58,输出结果为 "LVIII",解释如下:
    • 50 = "L"
    • 8 = "VIII",因为 5 (V) + 1 (I) + 1 (I) + 1 (I)
  • 输入 num = 1994,输出结果为 "MCMXCIV",解释如下:
    • 1000 = "M"
    • 900 = "CM",因为 1000 (M) - 100 ©
    • 90 = "XC",因为 100 © - 10 (X)
    • 4 = "IV",因为 5 (V) - 1 (I)

代码实现

cpp 复制代码
class Solution {
public:
    string intToRoman(int num) {
        string ans;
        vector<pair<int, string>> m = {
            {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 p : m) {
            while(num >= p.first) {
                num -= p.first;
                ans += p.second;
            }
        }
        return ans;
    }
};

代码解释

  1. 定义罗马数字映射表 :首先,我们使用 vector<pair<int, string>> 来存储每一个可能的数值和相应的罗马字符。这里按数值大小从高到低排序,便于逐步匹配。
  2. 贪心算法构建字符串 :接下来,遍历映射表中的每个 (值, 符号) 对。当输入整数大于等于当前值时,循环执行减去当前值并将相应符号添加到结果字符串。通过这个贪心算法,我们逐步构建最终的罗马数字表示。
  3. 终止条件:当输入整数逐步被减为0时,算法终止,最终字符串即为罗马数字。

时间复杂度与空间复杂度

时间复杂度 :O(1)。虽然存在一个 while 循环嵌套在 for 循环中,但我们处理的是有限数的整数符号对,映射表长度固定。故时间复杂度可以认为是常数时间。

空间复杂度:O(1)。代码只需要常量空间存储罗马数字符号对,以及一个字符串变量用于保存结果,因此空间复杂度为常数。

扩展思路

在不同的语言中实现该方法也相对容易。例如,在 Python 中可以使用类似的方法,也可以采用字典和字符串的拼接来表示相应的转换。需要注意的是,罗马数字规则虽然固定,但在一些特殊情况下仍需仔细考虑,比如在多层循环处理时可能会影响效率。贪心算法适用于此类问题,因为它确保每次选择的是当前情况下最佳的罗马符号。

总结

该解法基于贪心算法思想,通过逐步减去数值并附加罗马符号的方式实现整数到罗马数字的转换。代码清晰、易于理解,且高效处理所有可能的输入整数。总体上,这种方法不仅具有简单的逻辑流,也符合罗马数字的规则,尤其是减法表示法的运用。

相关推荐
qystca7 分钟前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱8 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子13 分钟前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
是阿建吖!14 分钟前
【优选算法】二分查找
c++·算法
王燕龙(大卫)18 分钟前
leetcode 数组中第k个最大元素
算法·leetcode
不去幼儿园1 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Mr_Xuhhh1 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
Ajiang28247353042 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
盼海2 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
网易独家音乐人Mike Zhou6 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot