Article / 文章
LeetCode 第273题:整数转换英文表示
将非负整数 num 转换为其对应的英文表示。
📖 文章摘要
本文详细解析LeetCode第273题“整数转换英文表示”,这是一道字符串处理和递归设计的困难问题。文章提供了从递归分治到迭代优化的完整解法思路,包含英语数字表示规律的深度分析和边界情况处理技巧,配有详细的算法分解过程和实现要点。适合想要掌握复杂字符串处理和递归算法设计的高级算法学习者。
核心知识点: 递归分治、字符串处理、英语数字规律、边界情况处理
难度等级: 困难
推荐人群: 字符串处理进阶者、递归算法设计者
题目描述
将非负整数 num 转换为其对应的英文表示。
示例
示例 1:
输入: num = 123
输出: "One Hundred Twenty Three"
示例 2:
输入: num = 12345
输出: "Twelve Thousand Three Hundred Forty Five"
示例 3:
输入: num = 1234567
输出: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
示例 4:
输入: num = 1234567891
输出: "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One"
提示
0 <= num <= 2^31 - 1
解题思路
这道题的关键在于理解英语数字表示的规律,并将复杂问题分解为简单的子问题。
核心分析
英语数字表示规律:
- 三位分组:英语中数字是每三位一组进行表示的
- 单位递增:从右到左依次是:个位、千位(Thousand)、百万位(Million)、十亿位(Billion)
- 特殊数字:需要特别处理小于20的数字和整十的数字
- 组合规则:每个三位组内部遵循相同的组合规则
解题策略:
- 创建基础数字词汇表(1-19, 20-90的整十数)
- 实现处理三位数的递归函数
- 从右到左每三位一组处理,添加相应单位
- 处理空格和边界情况
方法一:递归分治法
核心思想:
- 将问题分解为处理三位数的子问题
- 递归处理每个三位数组
- 根据位置添加相应的单位(Thousand, Million, Billion)
算法步骤:
- 特殊处理0的情况
- 创建基础词汇表
- 递归处理不同数量级的数字
- 组合结果并处理空格
复杂度分析:
- 时间复杂度:O(log n),其中n是输入数字,因为我们需要处理的位数是log₁₀(n)级别的
- 空间复杂度:O(1),除了存储结果字符串外,只使用了常数级别的额外空间
方法二:迭代法
核心思想:
- 使用迭代的方式从右到左处理每三位数
- 维护一个结果字符串,每次在前面插入新的部分
算法步骤:
- 预定义所有需要的单词数组
- 从低位开始每三位一组处理
- 为每组添加相应的单位
- 组合最终结果
复杂度分析:
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
图解思路
数字分解过程分析表
| 输入数字 | 分组 | 单位 | 处理结果 | 说明 |
|---|---|---|---|---|
| 1234567891 | 1 | Billion | “One Billion” | 十亿位处理 |
| 234567891 | 234 | Million | “Two Hundred Thirty Four Million” | 百万位处理 |
| 567891 | 567 | Thousand | “Five Hundred Sixty Seven Thousand” | 千位处理 |
| 891 | 891 | - | “Eight Hundred Ninety One” | 个位处理 |
三位数处理分析表
以567为例:
| 位置 | 数字 | 处理 | 结果部分 | 说明 |
|---|---|---|---|---|
| 百位 | 5 | 5 -> “Five” | “Five Hundred” | 添加Hundred |
| 十位 | 6 | 60 -> “Sixty” | “Sixty” | 整十数处理 |
| 个位 | 7 | 7 -> “Seven” | “Seven” | 个位数处理 |
| 最终 | 567 | 组合 | “Five Hundred Sixty Seven” | 空格连接 |
代码实现
C# 实现
public class Solution {
private readonly string[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
private readonly string[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
private readonly string[] THOUSANDS = {"", "Thousand", "Million", "Billion"};
public string NumberToWords(int num) {
if (num == 0) return "Zero";
int i = 0;
string words = "";
while (num > 0) {
if (num % 1000 != 0) {
words = Helper(num % 1000) + THOUSANDS[i] + " " + words;
}
num /= 1000;
i++;
}
return words.Trim();
}
private string Helper(int num) {
if (num == 0) return "";
else if (num < 20) return LESS_THAN_20[num] + " ";
else if (num < 100) return TENS[num / 10] + " " + Helper(num % 10);
else return LESS_THAN_20[num / 100] + " Hundred " + Helper(num % 100);
}
}
Python 实现
class Solution:
def numberToWords(self, num: int) -> str:
if num == 0:
return "Zero"
less_than_20 = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"]
tens = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"]
def helper(n):
if n < 20:
return less_than_20[n]
elif n < 100:
return tens[n // 10] + (" " + less_than_20[n % 10] if n % 10 else "")
elif n < 1000:
return less_than_20[n // 100] + " Hundred" + (" " + helper(n % 100) if n % 100 else "")
elif n < 1000000:
return helper(n // 1000) + " Thousand" + (" " + helper(n % 1000) if n % 1000 else "")
elif n < 1000000000:
return helper(n // 1000000) + " Million" + (" " + helper(n % 1000000) if n % 1000000 else "")
else:
return helper(n // 1000000000) + " Billion" + (" " + helper(n % 1000000000) if n % 1000000000 else "")
return helper(num)
C++ 实现
class Solution {
public:
string numberToWords(int num) {
if (num == 0) return "Zero";
vector<string> lessThan20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
vector<string> tens = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
vector<string> thousands = {"", "Thousand", "Million", "Billion"};
string result;
int groupIndex = 0;
while (num > 0) {
int group = num % 1000;
if (group > 0) {
string groupStr = helper(group, lessThan20, tens);
// 添加单位
if (groupIndex > 0) {
groupStr += " " + thousands[groupIndex];
}
// 插入到结果前面
if (!result.empty()) {
result = groupStr + " " + result;
} else {
result = groupStr;
}
}
num /= 1000;
groupIndex++;
}
return result;
}
private:
string helper(int num, vector<string>& lessThan20, vector<string>& tens) {
if (num < 20) {
return lessThan20[num];
} else if (num < 100) {
return tens[num / 10] + (num % 10 ? " " + lessThan20[num % 10] : "");
} else {
return lessThan20[num / 100] + " Hundred" + (num % 100 ? " " + helper(num % 100, lessThan20, tens) : "");
}
}
};
执行结果
C# 实现
- 执行用时:84 ms
- 内存消耗:40.2 MB
Python 实现
- 执行用时:52 ms
- 内存消耗:16.8 MB
C++ 实现
- 执行用时:0 ms
- 内存消耗:6.8 MB
性能对比
| 语言 | 执行用时 | 内存消耗 | 特点 |
|---|---|---|---|
| C++ | 0 ms | 6.8 MB | 性能最优,内存占用最小 |
| Python | 52 ms | 16.8 MB | 代码简洁,逻辑清晰 |
| C# | 84 ms | 40.2 MB | 结构化好,易于维护 |
代码亮点
- 🎯 递归分治思想完美体现,将复杂问题分解为处理三位数的简单子问题
- 💡 充分利用英语数字规律,通过预定义词汇表避免重复逻辑
- 🔍 边界情况处理完善,正确处理0、空格和各种数量级
- 🎨 代码结构清晰,递归函数职责单一,易于理解和扩展
常见错误分析
- 🚫 边界情况处理:输入为0时直接返回“Zero”,容易遗漏
- 🚫 空格处理:避免多余的空格,特别是在单词之间和结果末尾
- 🚫 大小写问题:每个单词的首字母都要大写,容易遗漏
- 🚫 数字范围:题目限制在2³¹-1以内,最大到Billion级别
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 递归分治法 | O(log n) | O(log n) | 代码简洁,逻辑清晰 | 递归调用有额外开销 |
| 迭代法 | O(log n) | O(1) | 空间效率高,无递归开销 | 代码稍复杂,需要手动管理状态 |
| 查表法 | O(1) | O(1) | 最快的查询速度 | 只适用于有限范围,表格庞大 |
相关题目
- LeetCode 12. 整数转罗马数字 - 中等
- LeetCode 13. 罗马数字转整数 - 简单
- LeetCode 8. 字符串转换整数 (atoi) - 中等
- LeetCode 65. 有效数字 - 困难
📖 系列导航
🔥 算法专题合集 - 查看完整合集
📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新第273题。
💬 互动交流
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
- 👍 点个赞,让更多人看到这篇文章
- 📁 收藏文章,方便后续查阅复习
- 🔔 关注作者,获取更多高质量算法题解
- 💭 评论区留言,分享你的解题思路或提出疑问
你的支持是我持续分享的动力!
💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!