Integer to English Words
Spell out a non-negative integer in English. Split it into groups of three digits (ones, thousands, millions, billions). Each group under 1000 is spelled with a small helper that handles hundreds, the teens, and tens; then append the group's scale word.
▶ Watch the animated traceTraced input: num = 1234567 → "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven". Original problem: leetcode.com/problems/integer-to-english-words/
Complexity
BestO(1)
AverageO(1)
WorstO(1)
SpaceO(1)
At most four groups for a 32-bit integer.
Key idea
- English repeats the same pattern for every three digits, plus a scale word.
- Numbers below 20 are irregular, so look them up directly.
- Skip groups that are 0 (no "Zero Thousand").
- Zero itself is a special case.
Common mistakes
- Printing "Zero" inside larger numbers.
- Extra or trailing spaces; trim at the end.
- Teens like 13 are not "Ten Three".
Solution
Java
static final String[] BELOW_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
static final String[] TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
static final String[] SCALES = {"", "Thousand", "Million", "Billion"};
String numberToWords(int num) {
if (num == 0) return "Zero";
String res = "";
int scale = 0;
while (num > 0) {
int chunk = num % 1000;
if (chunk != 0) res = three(chunk) + SCALES[scale] + " " + res;
num /= 1000;
scale++;
}
return res.trim();
}
String three(int n) {
String s = "";
if (n >= 100) {
s += BELOW_20[n / 100] + " Hundred ";
n %= 100;
}
if (n >= 20) {
s += TENS[n / 10] + " ";
n %= 10;
}
if (n > 0) s += BELOW_20[n] + " ";
return s;
}Python
BELOW_20 = ["", "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"]
SCALES = ["", "Thousand", "Million", "Billion"]
def numberToWords(num: int) -> str:
if num == 0: return "Zero"
res, scale = "", 0
while num > 0:
chunk = num % 1000
if chunk: res = three(chunk) + SCALES[scale] + " " + res
num //= 1000
scale += 1
return " ".join(res.split())
def three(n: int) -> str:
s = ""
if n >= 100:
s += BELOW_20[n // 100] + " Hundred "
n %= 100
if n >= 20:
s += TENS[n // 10] + " "
n %= 10
if n > 0: s += BELOW_20[n] + " "
return sC++
const vector<string> BELOW_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
const vector<string> TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
const vector<string> SCALES = {"", "Thousand", "Million", "Billion"};
string three(int n) {
string s;
if (n >= 100) {
s += BELOW_20[n / 100] + " Hundred ";
n %= 100;
}
if (n >= 20) {
s += TENS[n / 10] + " ";
n %= 10;
}
if (n > 0) s += BELOW_20[n] + " ";
return s;
}
string numberToWords(int num) {
if (num == 0) return "Zero";
string res;
int scale = 0;
while (num > 0) {
int chunk = num % 1000;
if (chunk != 0) res = three(chunk) + SCALES[scale] + " " + res;
num /= 1000;
scale++;
}
// collapse the extra spaces left by empty scale words
string out;
istringstream in(res);
for (string w; in >> w;) out += (out.empty() ? "" : " ") + w;
return out;
}Edge cases
Each one has its own trace in the interactive view.
| Case | Input | Answer |
|---|---|---|
| Zero Special case. | num = 0 | "Zero" |
| Teens and empty groups The thousands group is 0 and is skipped. | num = 1000013 | "One Million Thirteen" |
| Largest int All four groups are used. | num = 2147483647 | "Two Billion One Hundred Forty Seven Million Four Hundred Eighty Three Thousand Six Hundred Forty Seven" |
| Round hundred No trailing words. | num = 100 | "One Hundred" |