【困难】力扣算法题解析LeetCode273:整数转换英文表示
关注
文末推广名片,即可免费获得
本题测试源码
!
题目来源:LeetCode273:整数转换英文表示
问题抽象: 将非负整数 num
转换为符合美式英语规范的英文单词字符串,需满足以下核心需求:
-
转换规则定义:
- 分段处理:按 千位分段(
Thousand
、Million
、Billion
)逐级转换,每组 1-3 位数字 独立转换后添加单位; - 数字映射:
0-19
:特殊单词(如\"Zero\"
,\"Seventeen\"
);20-90
整十:复合单词(如\"Twenty\"
,\"Ninety\"
);- 三位组:按
百位 + \"Hundred\" + 十位个位
组合(如123 → \"One Hundred Twenty Three\"
)。
- 分段处理:按 千位分段(
-
格式要求:
- 单词格式:首字母大写,单词间 单空格分隔(无多余空格);
- 单位省略:
- 零值段跳过单位(如
1,000,001
不输出Million Thousand
); - 整百/整十段省略零单词(如
500 → \"Five Hundred\"
,不含\"Zero\"
)。
- 零值段跳过单位(如
-
边界处理:
num = 0
时返回\"Zero\"
;- 输入范围
0 ≤ num ≤ 2^31-1
(2,147,483,647
); - 禁止使用连接词(如
\"and\"
),遵循美式规范。
-
特殊场景:
- 连续零:
1,000,001 → \"One Million One\"
; - 十位个位组合:
115 → \"One Hundred Fifteen\"
(非\"One Hundred Ten Five\"
); - 大数分段:
1,234,567 → \"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven\"
。
- 连续零:
输入:整数 num
(如 1234567
)
输出:英文单词字符串(如 \"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven\"
)。
解题思路
核心思想:将数字按每三位一组划分(从低位到高位),分别处理每组的三位数,再结合单位(如千、百万、十亿)。通过预处理数组高效映射数字到单词,避免重复计算。
关键步骤
- 特殊处理 0:直接返回 “Zero”。
- 分组处理:将数字划分为四组(十亿、百万、千、个位),每组最多三位数。
- 三位数转换:
- 百位:直接映射数字并加上 “Hundred”。
- 十位和个位:
- 若小于 20,直接查表(0-19 有独立单词)。
- 若大于等于 20,拆分十位和个位分别映射(如 20 → “Twenty”)。
- 拼接结果:非空组才拼接,组间用空格分隔,避免首尾多余空格。
亮点
- 预处理数组:使用静态数组存储数字映射,避免重复生成。
- 惰性拼接:仅当组非空时才拼接,减少字符串操作。
- 高效取模:通过除法和取模快速获取各组值。
代码实现(Java版)🔥点击下载源码
class Solution { // 0-19 的英文单词 private static final String[] LESS_THAN_20 = { \"\", \"One\", \"Two\", \"Three\", \"Four\", \"Five\", \"Six\", \"Seven\", \"Eight\", \"Nine\", \"Ten\", \"Eleven\", \"Twelve\", \"Thirteen\", \"Fourteen\", \"Fifteen\", \"Sixteen\", \"Seventeen\", \"Eighteen\", \"Nineteen\" }; // 整十数的英文单词 private static final String[] TENS = { \"\", \"\", \"Twenty\", \"Thirty\", \"Forty\", \"Fifty\", \"Sixty\", \"Seventy\", \"Eighty\", \"Ninety\" }; // 单位数组(千、百万、十亿) private static final String[] THOUSANDS = { \"\", \"Thousand\", \"Million\", \"Billion\" }; public String numberToWords(int num) { if (num == 0) return \"Zero\"; // 直接处理 0 StringBuilder sb = new StringBuilder(); int groupIndex = 0; // 单位数组索引 while (num > 0) { int currentGroup = num % 1000; // 当前三位数组 if (currentGroup != 0) { // 处理当前组并拼接单位 String groupWords = convertThreeDigits(currentGroup); if (sb.length() > 0) { sb.insert(0, \" \"); // 非首组时前置空格 } sb.insert(0, groupWords + (THOUSANDS[groupIndex].isEmpty() ? \"\" : \" \" + THOUSANDS[groupIndex])); } num /= 1000; // 处理下一组 groupIndex++; } return sb.toString(); } // 转换三位数为英文单词 private String convertThreeDigits(int num) { if (num == 0) return \"\"; StringBuilder sb = new StringBuilder(); int hundred = num / 100; int remainder = num % 100; // 处理百位 if (hundred != 0) { sb.append(LESS_THAN_20[hundred]).append(\" Hundred\"); } // 处理剩余部分(十位和个位) if (remainder != 0) { if (sb.length() > 0) { sb.append(\" \"); // 百位非空时加空格 } if (remainder < 20) { sb.append(LESS_THAN_20[remainder]); // 0-19 直接查表 } else { int ten = remainder / 10; int one = remainder % 10; sb.append(TENS[ten]); // 十位单词 if (one != 0) { sb.append(\" \").append(LESS_THAN_20[one]); // 个位非空时追加 } } } return sb.toString(); }}
代码说明
-
预处理数组:
LESS_THAN_20
:存储 0-19 的英文单词(0 为空字符串,避免额外判断)。TENS
:存储 20-90 的整十数单词(索引 0-1 占位不用)。THOUSANDS
:存储单位(千、百万、十亿),索引对应组位置。
-
主函数
numberToWords
:- 分组处理:通过
num % 1000
获取当前组,num /= 1000
移至下一组。 - 惰性拼接:仅当组非空时,调用
convertThreeDigits
转换并拼接单位。 - 空格控制:非首组时插入前置空格,避免尾部多余空格。
- 分组处理:通过
-
辅助函数
convertThreeDigits
:- 百位处理:直接映射并追加 “Hundred”。
- 剩余部分:
< 20
:查LESS_THAN_20
表。≥ 20
:拆分十位/个位分别映射(如 45 → “Forty Five”)。