力扣刷题10

第一题:整数转罗马数字

来源:https://leetcode.cn/problems/integer-to-roman/

七个不同的符号代表罗马数字,其值如下:

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

罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:

  • 如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。
  • 如果该值以 4 或 9 开头,使用 减法形式 ,表示从以下符号中减去一个符号,例如 4 是 5 (V) 减 1 (I): IV ,9 是 10 (X) 减 1 (I):IX。仅使用以下减法形式:4 (IV),9 (IX),40 (XL),90 (XC),400 (CD) 和 900 (CM)。
  • 只有 10 的次方(I, X, C, M)最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V),50 (L) 或 500 (D)。如果需要将符号附加4次,请使用 减法形式

给定一个整数,将其转换为罗马数字。

这个题关键是读懂题目,就跟模拟一样,我用的是贪心的思想。

python 复制代码
class Solution:
    def intToRoman(self, num: int) -> str:
        # 构建值-符号映射表,按值从大到小排列
        value_symbols = [
            (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 = []
        for value, symbol in value_symbols:
            # 当当前值 <= num时,重复拼接符号并减去对应值
            while num >= value:
                roman.append(symbol)
                num -= value
            if num == 0:
                break
        return "".join(roman)

核心思想:罗马数字的构成规则是 "大值符号在前,小值在后",我们可以从最大的罗马数字值开始,不断用当前数字减去这个值,并在结果中拼接对应的符号,直到当前数字减到 0。

把所有可能的罗马数字组合(包括 4=IV9=IX 这类减法形式)都整理成一个降序的映射表,这样我们只需要从大到小遍历这个表,就能一步步拼出结果。

来模拟验证一下:(以3749为例)

1、3749 > 1000,拼接'M',3749-1000=2749

2、2749 > 1000,拼接'M',2749-1000=1749

3、1749 > 1000,拼接'M',1749-1000=749

4、749 > 500,拼接'D',749-500=249

5、249 > 100,拼接'C',249-100=149

6、149 > 100,拼接'C',149-100=49

7、49 > 40,拼接'XL',49-40=9

8、9 9,拼接'IX',9-9=0

最终结果为MMMDCCXLIX,和题目示例输出完全一致。


第二题:罗马数字转整数

来源:https://leetcode.cn/problems/roman-to-integer/description/

罗马数字包含以下七种字符: IVXLCDM

复制代码
字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II27 写做 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。

给定一个罗马数字,将其转换成整数。

python 复制代码
class Solution:
    def romanToInt(self, s: str) -> int:
        roman_map = {
            'I': 1,
            'V': 5,
            'X': 10,
            'L': 50,
            'C': 100,
            'D': 500,
            'M': 1000
        }
        total = 0
        n = len(s)
        for i in range(n):
            # 如果当前字符的值小于下一个,就减去当前值
            if i < n - 1 and roman_map[s[i]] < roman_map[s[i+1]]:
                total -= roman_map[s[i]]
            else:
                total += roman_map[s[i]]
        
        return total

这道题的核心思路是遍历罗马字符串,根据相邻字符的大小关系决定加或减

通常情况下,罗马数字是左大右小(如 VI → 5+1=6),直接相加即可;如果遇到左小右大的情况(如 IV → 5-1=4),就需要用右边的值减去左边的值。

我们可以统一遍历,当当前字符的值小于下一个字符的值时,就减去当前值;否则就加上当前值。

模拟验证一下:(以"IV"和"MCMXCIV"为例)

roman_map = 'IV'

i = 0时,roman_map[0] = I,I = 1,V = 5,I < V,total -= 1,total = -1;

i = 1时,roman_map[1] = V,V = 5,total += 5,total = 4

遍历结束,最终答案为4。

roman_map = 'MCMXCIV'

i = 0时,roman_map[0] = M,M = 1000,M > C(1000 > 100),total += 1000,total = 1000;

i = 1时,roman_map[1] = C,C = 100,C < M(100 < 1000),total -= 100,total = 900;

i = 2时,roman_map[2] = M,M = 1000,M > X(1000 > 10),total += 1000,total = 1900;

i = 3时,roman_map[3] = X,X = 10,X < C(10 < 100),total -= 10,total = 1890;

i = 4时,roman_map[4] = C,C = 100,C > I(100 > 1),total += 100,total = 1990;

i = 5时,roman_map[5] = I,I = 1,I < V(1 < 5),total -= 1,total = 1989;

i = 6时,roman_map[6] = V,V = 5,total += 5,total = 1994。

最终结果为1994。

所得结果与示例一致,搞定。

ok,记录完毕。

相关推荐
六义义2 小时前
java基础十二
java·数据结构·算法
四维碎片3 小时前
QSettings + INI 笔记
笔记·qt·算法
Tansmjs3 小时前
C++与GPU计算(CUDA)
开发语言·c++·算法
独自破碎E3 小时前
【优先级队列】主持人调度(二)
算法
weixin_445476684 小时前
leetCode每日一题——边反转的最小成本
算法·leetcode·职场和发展
打工的小王4 小时前
LeetCode Hot100(一)二分查找
算法·leetcode·职场和发展
Swift社区4 小时前
LeetCode 385 迷你语法分析器
算法·leetcode·职场和发展
sonadorje4 小时前
svd在图像处理中的应用
算法
挖矿大亨4 小时前
c++中的函数模版
java·c++·算法
测试老哥4 小时前
软件测试之功能测试详解
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例