LeetCode 补充题 14. 阿拉伯数字转中文数字

题目描述

补充题 14. 阿拉伯数字转中文数字

将一个整数转换为中文表示。例如:

  • 0
  • 1234一千二百三十四
  • 100010001一亿零一万零一
  • 10001一万零一
  • 1000一千

规则

  • 连续的零只读一个”零”
  • 末尾的零不读
  • 每4位一组,分别对应:个位、万位、亿位

思路分析

解法一:分组处理(推荐)

核心思路

  • 将数字按每4位一组进行分割,从高到低依次处理”亿”、”万”、”个”三个分组。
  • 每组内部处理千、百、十、个四个位,拼接对应的汉字。
  • 关键难点在于零的处理:
    1. 组内:当前位为0且前一位不为0,追加”零”;当前位为0且前一位也为0,跳过(避免连续零)。
    2. 组尾:去掉末尾的”零”(末尾零不读)。
    3. 跨组:若高位组不为零、低位组首位为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. 回文数 简单 数学 / 逐位处理
本文作者:
本文链接: https://hgnulb.github.io/blog/2024/95391996
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!