题目描述
思路解析动画文字版
切块法要先想清楚「哪两个字符要合并」,边界一多就容易写错。有没有不用提前切块的办法?
不用切块!逐个字符看:cur ,否则 → 加。比如 IV 的 I(1) 比右边 V(5) 小,就减 1;V 没有右边,就加 5。
盯住三件事:cur 指针在哪、当前符号和右邻谁大、total 怎么变。绿色 visited = 已处理完的格子。
i=0 · 看 M:cur 停在第 0 格 M(1000)。规则:要看它和右边那格谁大,才知道该加还是减。
i=0 · 锁定右邻:右边那格(变暗的)是 C(100)。把这两个数拎出来比:M 1000、C 100。
M(1000) > C(100) · 加:右邻是 C(100)。1000 > 100,不是减法形式 → 正常加。total 从 0 变 1000。
i=1 · 看 C:第 0 格 M 处理完变绿,cur 右移到第 1 格 C(100)。又要和右邻比了。
C(100) < M(1000) · 减!:右邻是 M(1000)。100 → 这个 C 是减法形式 CM 的前半,要减!total 反而从 1000 降到 900。这正是减法的精髓。
i=2 · 看 M:前两格 M、C 都处理完了(绿)。cur 来到第 2 格 M(1000),继续和右邻比。
M(1000) > X(10) · 加:右邻 X(10)。1000 > 10 → 正常加。total 升到 1900。这个 M 就是 CM 里的「大」那一半,加回来了。
i=3 · 看 X:cur 移到第 3 格 X(10)。又是熟悉的动作:看右边。
X(10) < C(100) · 减!:右邻 C(100)。10 → X 是减法形式 XC 的前半,减!total 降到 1890。
i=4 · 看 C:cur 到第 4 格 C(100)。注意同样是 C,这次右边不一样,结果就可能不同——继续比。
C(100) > I(1) · 加:右邻 I(1)。100 > 1 → 这个 C 正常加(它是 XC 里的大半)。total 升到 1990。
i=5 · 看 I:cur 到第 5 格 I(1),只剩最后两格了。还是先看右边。
I(1) < V(5) · 减!:右邻 V(5)。1 → I 是减法形式 IV 的前半,减!total 降到 1989。
i=6 · 看 V(最后一格):最后一格 V(5),右边没有字符了。没有右邻就不可能是减法形式 → 直接加。total = 1994!
全部处理完 · total = 1994:7 格全部走完。三处「小在大左边」的格子(C、X、I)做了减,其余做加,合起来正好 MCMXCIV = 1994。整条规则就这么简单。
再来一例 · IX:换个短例子 IX 巩固减法。cur 在第 0 格 I,右邻是 X。
IX · 锁定右邻:把右邻 X(10) 拎出来(变暗格)和 I(1) 比。明显 X 更大。
I(1) < X(10) · 减!:1 → I 减掉,total 先变成 −1。别慌,下一步 X 加回来。
X 加,IX = 9 ✓:X 没有右邻 → 加 10,total = −1 + 10 = 9。可见「先减小的、再加大的」自然就把 IX 算成 9,完全不用提前识别 IX 是个整体。
比如 IV:先加 I(=1),到 V 时发现上一个 I 比 V 小,于是 total = 1 + 5 − 2×1 = 4。和「向右看」是同一回事,代码里两种都常见,理解一种即可。
雷区实演 · 无脑全加:假如不做减法判断,IV 会被算成 1+5=6。正因为 I 在比它大的 V 左边要减,答案才是 4。这就是减法判断不能省的原因。
边界三连:先想纯加(III)、减法(IV)、混合(LVIII)三种,代码就稳了。
面试追问:把「为何只看右一格」和「O(n)」讲清楚,是这题面试的得分点。
参考代码
class Solution: def romanToInt(self, s): d = {'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 + 1 < n and d[s[i]] < d[s[i+1]]: # 小在大左边 total -= d[s[i]] # 减 else: total += d[s[i]] # 加 return total复杂度
- 时间复杂度:O(n),n = 字符串长度。每个字符只看一次,顺带瞄一眼右邻(O(1) 查表),总共扫一遍
- 空间复杂度:O(1),符号值表固定 7 项,只用一个 total 累加,与输入长度无关
易错点
面试追问把动画讲成自己的话
追问为什么向右看一格就够?
追问不查右邻能做吗?
追问反过来整数转罗马怎么做?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
加一
LeetCode 66 · 简单 · 沿着 数学套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题