Integer to English Words — Solution in Python, Java & C++
Integer to English Words solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A hard problem.
Integer to English Words is a hard coding problem on strings, math and recursion, asked in Amazon, Microsoft, Meta and Yahoo interviews.
- Difficulty: Hard
- Topics: Strings, Math, Recursion
- Asked at: Amazon, Microsoft, Meta, Yahoo, Yelp, Palantir, Oracle
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
CodeKairo's certificate printer writes amounts out in words. Given a non-negative integer num, return its English name.
Use the short-scale words Thousand, Million and Billion, write every word with a capital first letter, separate words with single spaces, and leave out "and" and hyphens: 123 is One Hundred Twenty Three. Zero is written Zero; a group of three digits that is all zeros contributes nothing (1000010 is One Million Ten).
Example 1
Input: num = 2026
Output: Two Thousand Twenty Six
Example 2
Input: num = 1000010
Output: One Million Ten
Explanation: The empty thousands group is skipped entirely.
Example 3
Input: num = 0
Output: Zero
Constraints
0 <= num <= 2^31 - 1
Hints for Integer to English Words
Hint 1
Split the number into groups of three digits from the right: billions, millions, thousands and units.
Hint 2
Every group is named the same way (a number below 1000) followed by its scale word — so write one helper for numbers below 1000.
Hint 3
Below 1000: an optional
X Hundred, then either a teen/unit word for 1–19 or a tens word plus an optional unit word. Skip groups that are zero, and special-casenum == 0.
How to solve Integer to English Words
English names numbers three digits at a time, so the whole task reduces to naming a number below 1000 and appending the right scale word to each non-empty group.
Approach
- If
num == 0, returnZero. - Keep tables for 1–19 (
One…Nineteen) and for the tens (Twenty…Ninety). - To name
g < 1000: ifg >= 100emit the hundreds digit andHundred; then for the remainingr = g % 100, emitTENS[r / 10]ifr >= 20and then the unit word if any, or the 1–19 word directly. - Walk the groups from the billions down:
g = (num / scale) % 1000. Ifg > 0, emit its name followed by the scale word (none for the units group). - Join all emitted words with single spaces.
Why it works
Each group of three digits is independent in English: its name does not depend on its neighbours, only on its own digits and its scale. Skipping zero groups and zero parts (no Zero inside a larger number, no Hundred without a hundreds digit) is exactly what makes 1000010 read One Million Ten.
Complexity
- Time —
O(1) — at most four groups - Space —
O(1)
Pitfalls
- Emitting
Zerofor an empty group or an empty units part, or leaving double spaces where a part is missing. - Numbers 10–19 are single words (
Eleven, notTen One). Fortyis spelled without a u.
Reference solution
Python
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"]
SCALES = ["", "Thousand", "Million", "Billion"]
def numberToWords(num: int) -> str:
if num == 0:
return "Zero"
groups = []
while num > 0:
groups.append(num % 1000)
num //= 1000
words = []
for g in range(len(groups) - 1, -1, -1):
if groups[g]:
_name_below_1000(groups[g], words)
if SCALES[g]:
words.append(SCALES[g])
return " ".join(words)
def _name_below_1000(n, out):
if n >= 100:
out.append(ONES[n // 100])
out.append("Hundred")
n %= 100
if n >= 20:
out.append(TENS[n // 10])
n %= 10
if n > 0:
out.append(ONES[n])Java
static final String[] NW_ONES = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
"Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
static final String[] NW_TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
static final String[] NW_SCALES = {"", "Thousand", "Million", "Billion"};
static void nwBelow1000(int n, List<String> out) {
if (n >= 100) {
out.add(NW_ONES[n / 100]);
out.add("Hundred");
n %= 100;
}
if (n >= 20) {
out.add(NW_TENS[n / 10]);
n %= 10;
}
if (n > 0) out.add(NW_ONES[n]);
}
public static String numberToWords(int num) {
if (num == 0) return "Zero";
int[] groups = new int[4];
int cnt = 0;
while (num > 0) {
groups[cnt++] = num % 1000;
num /= 1000;
}
List<String> words = new ArrayList<>();
for (int g = cnt - 1; g >= 0; g--) {
if (groups[g] > 0) {
nwBelow1000(groups[g], words);
if (g > 0) words.add(NW_SCALES[g]);
}
}
return String.join(" ", words);
}C++
static const char* NW_ONES[] = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
"Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
static const char* NW_TENS[] = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
static const char* NW_SCALES[] = {"", "Thousand", "Million", "Billion"};
static void nwBelow1000(int n, vector<string>& out) {
if (n >= 100) {
out.push_back(NW_ONES[n / 100]);
out.push_back("Hundred");
n %= 100;
}
if (n >= 20) {
out.push_back(NW_TENS[n / 10]);
n %= 10;
}
if (n > 0) out.push_back(NW_ONES[n]);
}
string numberToWords(int num) {
if (num == 0) return "Zero";
int groups[4];
int cnt = 0;
while (num > 0) {
groups[cnt++] = num % 1000;
num /= 1000;
}
vector<string> words;
for (int g = cnt - 1; g >= 0; g--) {
if (groups[g] > 0) {
nwBelow1000(groups[g], words);
if (g > 0) words.push_back(NW_SCALES[g]);
}
}
string res;
for (size_t i = 0; i < words.size(); i++) {
if (i) res += ' ';
res += words[i];
}
return res;
}JavaScript
var NW_ONES = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
"Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"];
var NW_TENS = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
var NW_SCALES = ["", "Thousand", "Million", "Billion"];
function nwBelow1000(n, out) {
if (n >= 100) {
out.push(NW_ONES[Math.floor(n / 100)], "Hundred");
n %= 100;
}
if (n >= 20) {
out.push(NW_TENS[Math.floor(n / 10)]);
n %= 10;
}
if (n > 0) out.push(NW_ONES[n]);
}
var numberToWords = function(num) {
if (num === 0) return "Zero";
var groups = [];
while (num > 0) {
groups.push(num % 1000);
num = Math.floor(num / 1000);
}
var words = [];
for (var g = groups.length - 1; g >= 0; g--) {
if (groups[g] > 0) {
nwBelow1000(groups[g], words);
if (g > 0) words.push(NW_SCALES[g]);
}
}
return words.join(" ");
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.