LeetCode 补充题 14. 阿拉伯数字转中文数字
题目描述
将一个整数转换为中文表示。例如:
-
0→零 -
1234→一千二百三十四 -
100010001→一亿零一万零一 -
10001→一万零一 -
1000→一千
规则:
- 连续的零只读一个”零”
- 末尾的零不读
- 每4位一组,分别对应:个位、万位、亿位
思路分析
解法一:分组处理(推荐)
核心思路:
- 将数字按每4位一组进行分割,从高到低依次处理”亿”、”万”、”个”三个分组。
- 每组内部处理千、百、十、个四个位,拼接对应的汉字。
- 关键难点在于零的处理:
- 组内:当前位为0且前一位不为0,追加”零”;当前位为0且前一位也为0,跳过(避免连续零)。
- 组尾:去掉末尾的”零”(末尾零不读)。
- 跨组:若高位组不为零、低位组首位为0,需在组间插入”零”(如”一亿零一万”)。
- 特殊情况:整体结果为空时,返回”零”。
复杂度分析:
- 时间复杂度:O(1),数字最多 13 位,处理位数固定,与输入大小无关。
- 空间复杂度:O(1),辅助数组和 StringBuilder 的大小均为常数级别。
class Solution {
// 数字汉字映射
private static final String[] DIGITS = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
// 组内位权
private static final String[] UNITS = {"", "十", "百", "千"};
// 分组权重(个、万、亿)
private static final String[] GROUPS = {"", "万", "亿"};
public String numberToChinese(int num) {
if (num == 0) {
return "零";
}
// 将数字拆分为三组(个、万、亿),每组最多4位
int[] parts = new int[3];
parts[0] = num % 10000;
parts[1] = (num / 10000) % 10000;
parts[2] = num / 100000000;
StringBuilder result = new StringBuilder();
for (int i = 2; i >= 0; i--) {
if (parts[i] == 0) {
continue;
}
// 处理当前分组的4位数字
String groupStr = processGroup(parts[i]);
// 若高位组已有内容且低位组首位为0,需补"零"
if (result.length() > 0 && parts[i] < 1000) {
result.append("零");
}
result.append(groupStr).append(GROUPS[i]);
}
return result.toString();
}
/**
* 处理4位以内的数字,转换为汉字字符串
*/
private String processGroup(int num) {
StringBuilder sb = new StringBuilder();
// 从千位到个位依次处理
int[] positions = {1000, 100, 10, 1};
boolean lastZero = false;
for (int i = 0; i < 4; i++) {
int digit = num / positions[i];
num %= positions[i];
if (digit == 0) {
// 当前位为0,标记,后续若有非零位则补"零"
if (sb.length() > 0) {
lastZero = true;
}
} else {
// 有非零位时,先补上积累的"零"
if (lastZero) {
sb.append("零");
lastZero = false;
}
sb.append(DIGITS[digit]).append(UNITS[3 - i]);
}
}
return sb.toString();
}
}
var digits = []string{"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"}
var units = []string{"", "十", "百", "千"}
var groups = []string{"", "万", "亿"}
func numberToChinese(num int) string {
if num == 0 {
return "零"
}
// 将数字拆分为三组(个、万、亿),每组最多4位
parts := [3]int{
num % 10000,
(num / 10000) % 10000,
num / 100000000,
}
var result strings.Builder
for i := 2; i >= 0; i-- {
if parts[i] == 0 {
continue
}
// 处理当前分组的4位数字
groupStr := processGroup(parts[i])
// 若高位组已有内容且低位组首位为0,需补"零"
if result.Len() > 0 && parts[i] < 1000 {
result.WriteString("零")
}
result.WriteString(groupStr)
result.WriteString(groups[i])
}
return result.String()
}
// processGroup 处理4位以内的数字,转换为汉字字符串
func processGroup(num int) string {
var sb strings.Builder
positions := [4]int{1000, 100, 10, 1}
lastZero := false
for i := 0; i < 4; i++ {
digit := num / positions[i]
num %= positions[i]
if digit == 0 {
// 当前位为0,标记,后续若有非零位则补"零"
if sb.Len() > 0 {
lastZero = true
}
} else {
// 有非零位时,先补上积累的"零"
if lastZero {
sb.WriteString("零")
lastZero = false
}
sb.WriteString(digits[digit])
sb.WriteString(units[3-i])
}
}
return sb.String()
}
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 273. 整数转换英文表示 | 困难 | 字符串 / 分组处理 |
| 12. 整数转罗马数字 | 中等 | 字符串 / 贪心映射 |
| 13. 罗马数字转整数 | 简单 | 字符串 / 哈希映射 |
| 168. Excel 表列名称 | 简单 | 数学 / 进制转换 |
| 171. Excel 表列序号 | 简单 | 数学 / 进制转换 |
| 7. 整数反转 | 中等 | 数学 / 逐位处理 |
| 9. 回文数 | 简单 | 数学 / 逐位处理 |
本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0
许可协议,转载请注明出处!