news 2026/9/13 11:36:11

LeetCode-Go 题解精讲:13. Roman to Integer 罗马数字转整数(Go 实现)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode-Go 题解精讲:13. Roman to Integer 罗马数字转整数(Go 实现)

LeetCode-Go 题解精讲:13. Roman to Integer 罗马数字转整数(Go 实现)

【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go

导读

本文以 LeetCode 第 13 题Roman to Integer(罗马数字转整数)为核心,完整讲解题目规则、六类减法特例,并逐行剖析 LeetCode-Go 仓库中romanToInt的 Go 实现与配套测试。读完本文,你将掌握罗马数字「大数在前为加、小数在前为减」的解析规律,理解单次线性扫描即可完成转换的算法思路,并能直接运行本仓库的测试用例验证正确性。

一、题目描述

罗马数字由以下七种不同符号表示:

符号 Symbol数值 Value
I1
V5
X10
L50
C100
D500
M1000

例如,数字 2 写作II,即两个 1 相加;12 写作XII,即X + II;27 写作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。

题目要求:给定一个罗马数字,将其转换成整数。输入保证在 1 到 3999 的范围内。

二、官方示例

示例输入输出说明
示例 1"III"3三个 1 相加
示例 2"IV"41 在 5 前,做减法
示例 3"IX"91 在 10 前,做减法
示例 4"LVIII"58L = 50, V = 5, III = 3
示例 5"MCMXCIV"1994M = 1000, CM = 900, XC = 90, IV = 4

以示例 5 的MCMXCIV为例,它可拆解为M + CM + XC + IV,即1000 + 900 + 90 + 4 = 1994,正是减法规则与加法规则混合使用的典型场景。

三、解题思路

本题属于简单题:按照题目给出的罗马数字字符数值,逐位计算出对应的十进制数即可。

关键观察是:「小数在左」意味着减法,「小数在右」意味着加法。因此有两种经典解法:

  1. 从左到右扫描:比较当前字符与下一字符的数值,若当前值小于下一值,则减去当前值,否则加上当前值;
  2. 从右到左扫描(本仓库采用):维护一个lastint记录「右边相邻字符」的数值,若当前字符数值小于右边字符数值,说明出现了减法组合,做减法;否则做加法。

从右到左扫描的优势是只需一次遍历即可完成全部处理,时间复杂度 O(n),空间复杂度 O(1),n 为字符串长度(题目限制 n 最大对应 3999,即最多约 15 个字符)。

四、Go 实现逐行剖析

LeetCode-Go 仓库中该题的实现位于 leetcode/0013.Roman-to-Integer/13. Roman to Integer.go,完整代码如下:

package leetcode var roman = map[string]int{ "I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000, } func romanToInt(s string) int { if s == "" { return 0 } num, lastint, total := 0, 0, 0 for i := 0; i < len(s); i++ { char := s[len(s)-(i+1) : len(s)-i] num = roman[char] if num < lastint { total = total - num } else { total = total + num } lastint = num } return total }

4.1 符号表roman

代码通过包级变量roman建立「字符 → 数值」的映射表,与题目给出的七种符号一一对应。这种 map 查表方式可读性强、扩展方便,是处理有限字符集映射的常用做法。

4.2 空串防护

if s == "" { return 0 }

对空字符串直接返回 0,避免后续切片操作越界。这一点也在仓库测试用例中得到了覆盖(见下文测试章节)。

4.3 从右向左的减法判定

num, lastint, total := 0, 0, 0 for i := 0; i < len(s); i++ { char := s[len(s)-(i+1) : len(s)-i] num = roman[char] if num < lastint { total = total - num } else { total = total + num } lastint = num }

核心逻辑分四步:

  1. 反向取字符s[len(s)-(i+1) : len(s)-i]从字符串末尾向开头逐个截取单字符(用切片而非char字节,是为了直接作为 map 的 string 键);
  2. 查表取值num = roman[char]得到当前字符数值;
  3. 比较并累加:若num < lastint,说明当前字符在它右边较大数字的左边,构成减法组合(如IVIXXCCM),从总数中减去num;否则直接加上num
  4. 更新lastint:记录已处理的右边字符数值,供下一次迭代比较。

4.3.1 以IV为例推演

  • 反向取到Vnum = 5lastint = 05 >= 0total = 5lastint = 5
  • 反向取到Inum = 11 < 5,判定为减法,total = 5 - 1 = 4

最终返回 4,与题目示例一致。

4.3.2 以MCMXCIV为例推演

从右往左依次处理V → I → C → X → M → C → M

处理字符numlastint(右边值)运算total
V50+55
I15-1(1 < 5)4
C1001+100104
X10100-10(10 < 100)94
M100010+10001094
C1001000-100(100 < 1000)994
M1000100+10001994

最终返回 1994,与题目示例 5 完全吻合。可以看到,减法组合(IVXCCM)都在反向扫描中被自动识别。

五、测试用例与验证

该题测试位于 leetcode/0013.Roman-to-Integer/13. Roman to Integer_test.go,采用「参数-答案」结构体驱动的表驱动测试:

type question13 struct { para13 ans13 } type para13 struct { one string } type ans13 struct { one int } func Test_Problem13(t *testing.T) { qs := []question13{ {para13{"III"}, ans13{3}}, {para13{"IV"}, ans13{4}}, {para13{"IX"}, ans13{9}}, {para13{"LVIII"}, ans13{58}}, {para13{"MCMXCIV"}, ans13{1994}}, {para13{"MCMXICIVI"}, ans13{2014}}, {para13{""}, ans13{0}}, } for _, q := range qs { a, p := q.ans13, q.para13 got := romanToInt(p.one) if got != a.one { t.Fatalf("input %q: got %d, want %d", p.one, got, a.one) } } }

5.1 用例覆盖分析

测试用例不仅覆盖了题目给出的全部五个示例(IIIIVIXLVIIIMCMXCIV),还额外补充了两个边界场景:

  • "MCMXICIVI" → 2014:混合长字符串的鲁棒性验证;
  • "" → 0:空串边界,直接对应源码第 15~17 行的空串防护分支。

5.2 运行方式

在仓库根目录下运行单题测试:

go test -v ./leetcode/0013.Roman-to-Integer/

若希望运行全部题目的测试并输出覆盖率,可直接使用仓库自带的 gotest.sh 脚本(其内部执行go test -covermode=atomic -coverprofile=coverage.txt ./leetcode/...):

bash gotest.sh

六、与逆运算 12. Integer to Roman 的对照

罗马数字相关的另一道题是 LeetCode 第 12 题 Integer to Roman(整数转罗马数字),本仓库的实现位于 leetcode/0012.Integer-to-Roman/12. Integer to Roman.go:

func intToRoman(num int) string { values := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1} symbols := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"} res, i := "", 0 for num != 0 { for values[i] > num { i++ } num -= values[i] res += symbols[i] } return res }

两道题互为逆运算,可对照学习:

  • 第 13 题将罗马数字解析为整数,核心是「识别减法组合」(小数在前即减);
  • 第 12 题将整数编码为罗马数字,核心是把四类减法组合(CMCDXCXLIXIV)与常规符号一起按降序贪心取值。

值得注意的是,第 12 题把900/400/90/40/9/4等减法组合直接编码为独立符号单元,这恰好印证了第 13 题反向扫描时「num < lastint即做减法」的判定与罗马数字本身的编码结构是自洽的——一个合法罗马数字串中,只要出现小数在前的相邻对,必然属于六类减法特例之一。

七、小结

本题的关键要点可归纳为:

  1. 规则本质:罗马数字「左减右加」,六类减法特例覆盖所有小数在前的情况;
  2. 算法核心:一次反向扫描,通过与右边已处理字符的数值比较即可同时处理加减,无需预判组合;
  3. 实现技巧:map 符号表 + 切片取字符 +lastint游标,代码简洁且空间复杂度 O(1);
  4. 工程规范:仓库代码遵循 Google Golang Style Guide,配套表驱动测试覆盖示例与边界,可通过 gotest.sh 一键运行全部测试并生成覆盖率报告。

无论是准备面试还是巩固字符串解析基本功,将本仓库的 源码实现 与 测试用例 对照研读,都是最快掌握该题解法的路径。

【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 11:34:40

Zulip Heroku 集成:将应用构建与发布事件实时推送到团队聊天

Zulip Heroku 集成&#xff1a;将应用构建与发布事件实时推送到团队聊天 【免费下载链接】zulip Zulip server and web application. Open-source team chat that helps teams stay productive and focused. 项目地址: https://gitcode.com/GitHub_Trending/zu/zulip 本…

作者头像 李华
网站建设 2026/9/13 11:31:49

AUTOSAR BswM模块:汽车ECU模式管理核心解析

1. AUTOSAR BswM模块概述BswM&#xff08;Basic Software Mode Manager&#xff09;是AUTOSAR标准中的核心系统服务模块&#xff0c;负责协调ECU内部不同模块的工作模式与状态转换。作为AUTOSAR基础软件&#xff08;BSW&#xff09;的关键组件&#xff0c;它通过规则驱动的决策…

作者头像 李华
网站建设 2026/9/13 11:28:09

ESP32避障小车:从接线到自主巡行的4阶段搭建路径

ESP32避障小车&#xff1a;从接线到自主巡行的4阶段搭建路径 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 当测试台架没有网络、小车需要自己完成一圈巡逻时&#xff0c…

作者头像 李华
网站建设 2026/9/13 11:27:37

Stable Diffusion WebUI Forge 上手指南:从克隆到出图只需10分钟

Stable Diffusion WebUI Forge 上手指南&#xff1a;从克隆到出图只需10分钟 【免费下载链接】stable-diffusion-webui-forge 项目地址: https://gitcode.com/GitHub_Trending/st/stable-diffusion-webui-forge Stable Diffusion WebUI Forge 是基于 SD-WebUI 1.10.1 的…

作者头像 李华