273. 整数转换英文表示
题目描述
输入一个非负整数 num,把它转写成英文读法并以字符串返回。
按英文习惯,每三位一组,分别带上 Thousand、Million、Billion 等单位;每组内用 Hundred 以及 Twenty、Thirty 之类的十位词和 One 到 Nineteen 的基础词表示。为零的部分不读出来,num = 0 时返回 "Zero"。
每个单词首字母大写,单词之间只用一个空格隔开,开头和结尾都不能有空格。
示例 1
输入:num = 123 输出:"One Hundred Twenty Three"
解释:123 读作一百二十三。
示例 2
输入:num = 12345 输出:"Twelve Thousand Three Hundred Forty Five"
解释:12345 拆成 12 千和 345。
示例 3
输入:num = 1234567 输出:"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
解释:1234567 拆成 1 百万、234 千和 567。
数据范围
0 <= num <= 2^31 - 1
解题思路
英文读数是三位一组:从高到低依次是 Billion、Million、Thousand 和最后三位。对每一组 part = num // 1000^i % 1000,若为 0 就整组跳过;否则按“百位 → 20 及以上的整十 → 1–19”三段拼出单词,再跟上这一组的单位。所有单词放进列表,最后用一个空格连接,天然不会有多余空格。
为什么正确
处理完第 i 组后,res 是 num 中高于 1000^i 的部分的英文读法。
复杂度分析
时间 O(1):最多 4 组,每组至多 4 个单词;空间 O(1)。
易错点
容易出错的地方有三个:num = 0 要单独返回 "Zero";10–19 是不规则单词,不能拆成“十位 + 个位”;像 1000000 这样的数,整组为 0 时不能输出单位(不能出现 "One Million Thousand")。
参考代码
Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。
class Solution:
def numberToWords(self, num: int) -> str:
if num == 0:
return 'Zero'
ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen']
tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']
units = ['', 'Thousand', 'Million', 'Billion']
res = []
for i in range(3, -1, -1):
part = num // 1000 ** i % 1000
if part == 0:
continue
words = []
if part >= 100:
words += [ones[part // 100], 'Hundred']
part %= 100
if part >= 20:
words.append(tens[part // 10])
part %= 10
if part > 0:
words.append(ones[part])
if units[i]:
words.append(units[i])
res += words
return ' '.join(res)class Solution {
public String numberToWords(int num) {
if (num == 0) {
return "Zero";
}
String[] ones = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
String[] tens = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
String[] units = {"", "Thousand", "Million", "Billion"};
List<String> res = new ArrayList<>();
long[] scale = {1L, 1000L, 1000000L, 1000000000L};
for (int i = 3; i >= 0; i--) {
int part = (int) (num / scale[i] % 1000);
if (part == 0) {
continue;
}
List<String> words = new ArrayList<>();
if (part >= 100) {
words.add(ones[part / 100]);
words.add("Hundred");
part %= 100;
}
if (part >= 20) {
words.add(tens[part / 10]);
part %= 10;
}
if (part > 0) {
words.add(ones[part]);
}
if (!units[i].isEmpty()) {
words.add(units[i]);
}
res.addAll(words);
}
return String.join(" ", res);
}
}class Solution {
public:
string numberToWords(int num) {
if (num == 0) {
return "Zero";
}
vector<string> ones = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
vector<string> tens = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
vector<string> units = {"", "Thousand", "Million", "Billion"};
vector<string> res;
long long scale[4] = {1, 1000, 1000000, 1000000000};
for (int i = 3; i >= 0; i--) {
int part = (int)(num / scale[i] % 1000);
if (part == 0) {
continue;
}
vector<string> words;
if (part >= 100) {
words.push_back(ones[part / 100]);
words.push_back("Hundred");
part %= 100;
}
if (part >= 20) {
words.push_back(tens[part / 10]);
part %= 10;
}
if (part > 0) {
words.push_back(ones[part]);
}
if (!units[i].empty()) {
words.push_back(units[i]);
}
for (auto& w : words) res.push_back(w);
}
string out;
for (size_t k = 0; k < res.size(); k++) {
if (k) out += " ";
out += res[k];
}
return out;
}
};func numberToWords(num int) string {
if num == 0 {
return "Zero"
}
ones := []string{"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
tens := []string{"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}
units := []string{"", "Thousand", "Million", "Billion"}
res := []string{}
scale := []int{1, 1000, 1000000, 1000000000}
for i := 3; i >= 0; i-- {
part := num / scale[i] % 1000
if part == 0 {
continue
}
words := []string{}
if part >= 100 {
words = append(words, ones[part/100], "Hundred")
part %= 100
}
if part >= 20 {
words = append(words, tens[part/10])
part %= 10
}
if part > 0 {
words = append(words, ones[part])
}
if units[i] != "" {
words = append(words, units[i])
}
res = append(res, words...)
}
return strings.Join(res, " ")
}var numberToWords = function(num) {
if (num === 0) {
return 'Zero';
}
const ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
const tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
const units = ['', 'Thousand', 'Million', 'Billion'];
const res = [];
for (let i = 3; i >= 0; i--) {
let part = Math.floor(num / 1000 ** i) % 1000;
if (part === 0) {
continue;
}
const words = [];
if (part >= 100) {
words.push(ones[Math.floor(part / 100)], 'Hundred');
part %= 100;
}
if (part >= 20) {
words.push(tens[Math.floor(part / 10)]);
part %= 10;
}
if (part > 0) {
words.push(ones[part]);
}
if (units[i]) {
words.push(units[i]);
}
res.push(...words);
}
return res.join(' ');
};function numberToWords(num: number): string {
if (num === 0) {
return 'Zero';
}
const ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
const tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
const units = ['', 'Thousand', 'Million', 'Billion'];
const res: string[] = [];
for (let i = 3; i >= 0; i--) {
let part = Math.floor(num / 1000 ** i) % 1000;
if (part === 0) {
continue;
}
const words: string[] = [];
if (part >= 100) {
words.push(ones[Math.floor(part / 100)], 'Hundred');
part %= 100;
}
if (part >= 20) {
words.push(tens[Math.floor(part / 10)]);
part %= 10;
}
if (part > 0) {
words.push(ones[part]);
}
if (units[i]) {
words.push(units[i]);
}
res.push(...words);
}
return res.join(' ');
}