整数转换英文表示
难度:
标签:
题目描述
将非负整数 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"
提示:
0 <= num <= 231 - 1
代码结果
运行时间: 26 ms, 内存: 16.1 MB
/*
* 将非负整数 num 转换为其对应的英文表示。
* 使用Java Stream
*/
import java.util.*;
import java.util.stream.Collectors;
public class NumberToWordsStream {
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";
List<String> parts = new ArrayList<>();
int i = 0;
while (num > 0) {
if (num % 1000 != 0) {
parts.add(0, helper(num % 1000) + THOUSANDS[i]);
}
num /= 1000;
i++;
}
return parts.stream().filter(str -> !str.isEmpty()).collect(Collectors.joining(" ")).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);
}
}
解释
方法:
解题思路主要基于对数字的逐段解析,将整数划分为若干三位数的段,每个段内单独处理,并转换为英文表述。首先定义四个列表,分别表示个位数、十位数中的特殊情况(10到19)、普通的十位数后缀(20, 30, ...),以及千位数的后缀(千、百万、十亿)。主要函数使用递归处理每个三位数的段,再将这些段结合千位数后缀组合起来形成完整的英文表述。递归函数处理小于10的数返回对应的英文,处理小于20的数返回特殊的青少年数字英文,处理小于100的数将十位和个位分开处理,处理三位数时将百位、十位和个位分开处理。整个数按千的倍数逐步减少,每处理完一个三位数的段,就添加相应的千位后缀。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在将数字分为三位数段的方法中,递归函数是如何确保不会遗漏处理某些数字的,特别是在数字边界(如1000,1000000)的情况下?
▷🦆
为什么选择递归作为处理每个三位数的主要方法,而不是迭代或其他可能的解决方案?
▷🦆
在处理特殊的十位数(10到19)时,这种方法如何保证其正确性,尤其是在数的组合需要区分特殊读法和普通读法的情况下?
▷🦆
对于极大或极小的输入值(如0或接近2^31 - 1的值),这个算法的效率如何?是否有可能对其进行优化?
▷相关问题
整数转罗马数字
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 罗马数字 2 写做 II
,即为两个并列的 1。12 写做 XII
,即为 X
+ II
。 27 写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给你一个整数,将其转为罗马数字。
示例 1:
输入: num = 3 输出: "III"
示例 2:
输入: num = 4 输出: "IV"
示例 3:
输入: num = 9 输出: "IX"
示例 4:
输入: num = 58 输出: "LVIII" 解释: L = 50, V = 5, III = 3.
示例 5:
输入: num = 1994 输出: "MCMXCIV" 解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= num <= 3999