LeetCode 1556. 千位分隔数
题目描述
题意分析
给一个非负整数,把它写成字符串,并且每三位数字之间插入一个点作为分隔符,返回这个字符串。注意分隔符是英文句点
.,不是常见的逗号。要点在于「每三位」是从右往左数的,而不是从左往右。因为最高位那一组的长度取决于总位数模 3 的余数,可能是 1 位、2 位或 3 位,只有从低位开始数才能自动得到正确的分组。
约束信号是
n最大到 2³¹ - 1,也就是十位数,位数很少,怎么写都不会超时;真正被考察的是边界处理是否干净,而不是效率。边界包括:
n = 0时循环体一次都不会执行,必须保证返回"0"而不是空串;位数恰好是 3 的倍数时(比如 123456),最高位前面绝不能多出一个点;位数不足 4 位时(比如 987),一个点都不该出现。
解法:从低位分组构造
核心思路
千位分组必须从右端开始,因为最高位组可能只有 1 到 3 位。直接从低位取数:每轮用
n % 10取出一位并写入缓冲区,用n /= 10删除这一位;每写满三位,若仍有更高位,就追加分隔点。循环不变量是:缓冲区保存了已经处理的低位部分的逆序表示,
count是当前组已写入的数字数。插点条件必须同时满足count == 3和n > 0:前者保证每组三位,后者保证最高位组前不会多出一个点。因为数字按低位到高位写入,最后整体反转即可得到答案。
n = 0时循环不会执行,需要单独返回"0"。
解题步骤
- 若
n == 0,直接返回"0"。- 反复取
n % 10,把当前最低位追加到缓冲区,并令n /= 10。- 当前组计数加一;当计数达到 3 且
n > 0时追加.,再把计数清零。- 数字处理完后反转缓冲区并返回。
以
1234567为例,低位方向依次写出765.432.1,反转后得到1.234.567。对于123456,处理最高三位后n已为 0,因此不会在最前面多加分隔点。
代码实现
class Solution {
public String thousandSeparator(int n) {
if (n == 0) {
return "0";
}
StringBuilder reversed = new StringBuilder();
int count = 0;
while (n > 0) {
reversed.append((char) ('0' + n % 10));
n /= 10;
count++;
if (count == 3 && n > 0) {
reversed.append('.');
count = 0;
}
}
return reversed.reverse().toString();
}
}
func thousandSeparator(n int) string {
if n == 0 {
return "0"
}
reversed := make([]byte, 0)
count := 0
for n > 0 {
reversed = append(reversed, byte('0'+n%10))
n /= 10
count++
if count == 3 && n > 0 {
reversed = append(reversed, '.')
count = 0
}
}
for left, right := 0, len(reversed)-1; left < right; left, right = left+1, right-1 {
reversed[left], reversed[right] = reversed[right], reversed[left]
}
return string(reversed)
}
复杂度分析
- 时间复杂度:$O(d)$,其中 $d$ 是十进制位数;逐位处理和最终反转各扫描一次。
- 空间复杂度:$O(d)$,用于保存数字和分隔点组成的结果。
关键点总结
- 分组从右端开始,最高位组的长度才无需特判。
- 插点条件是
count == 3 && n > 0,其中n > 0专门避免前导分隔点。- 低位到高位的构造顺序与结果相反,因此最后必须反转。
- 0 是唯一不会进入循环但仍需输出一位数字的输入。
易错点总结
- 未特判
n == 0,会返回空字符串。- 只判断
count == 3:123456会得到.123.456。- 插点后未把计数清零:
1234567只会产生一个分隔点。- 忘记反转:
1234567会返回765.432.1。- 使用逗号而不是题目要求的英文句点
.。
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 7. 整数反转 | 中等 | 逐位取模与溢出判断 |
| 8. 字符串转换整数 (atoi) | 中等 | 状态机式字符串解析 |
| 12. 整数转罗马数字 | 中等 | 贪心按面值拆分 |
| 273. 整数转换英文表示 | 困难 | 三位一组的递归拼写 |
| 68. 文本左右对齐 | 困难 | 分组与末行特殊格式 |