Integer to English Words

Integer to English Words sounds easy until you try it. Turn a number like 1234567 into the words you would say out loud. The interviewer wants to see if you can break a big messy problem into small clean parts. That skill is the whole point here.

🎯 The Problem

You turn a number into the English words you would say out loud.

  • For example 123 becomes "One Hundred Twenty Three".
  • We say big numbers in groups of three digits, the way we read them in real life.
  • Each group has its own name. The lowest is plain. Then thousand. Then million. Then billion.
  • So 1234567 is one million, two hundred thirty four thousand, five hundred sixty seven.

We use 1234567 as our example.

Input: num = 1234567
Output: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
Explanation: 1 -> One Million, 234 -> Two Hundred Thirty Four Thousand, 567 -> Five Hundred Sixty Seven

Here is how the number splits into three-digit groups, where a three-digit group is a chunk of up to three digits read from the right.

1234567

group 1 -> Million

group 234 -> Thousand

group 567 -> ones

One Million

Two Hundred Thirty Four Thousand

Five Hundred Sixty Seven

🐒 Approach 1: Digit by Digit (Brute Force)

The idea in one line: read one digit at a time and spell each digit.

The idea:

  • Read the digits one by one.
  • So 123 becomes β€œone two three”.

Why it is weak:

  • We do not say numbers that way. We say β€œone hundred twenty three”.
  • The trouble is place value, the worth of a digit based on its position.
  • The same 2 means twenty in 123 but two in 213. Single digits lose that meaning.

Here is a direct chunk-based version of that idea:

integer_to_english_words_direct.py
def number_to_words(num):
if num == 0:
return "Zero"
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"]
def chunk_to_words(n):
words = []
if n >= 100:
words += [below_20[n // 100], "Hundred"]
n %= 100
if n >= 20:
words.append(tens[n // 10])
n %= 10
if n > 0:
words.append(below_20[n])
return words
parts = []
for value, name in [(10**9, "Billion"), (10**6, "Million"), (1000, "Thousand"), (1, "")]:
chunk = num // value
if chunk:
parts.extend(chunk_to_words(chunk))
if name:
parts.append(name)
num %= value
return " ".join(parts)

⚑ Approach 2: Three-Digit Groups (Best)

The idea in one line: spell three digits at a time with one reusable helper, then add the group name.

The idea:

  • Break the number into groups of three digits from the right.
  • The lowest group is ones. Then thousands. Then millions. Then billions.
  • Attach the right name to each group.

How it works:

  • Write one helper that spells any number from 1 to 999. It does hundreds, then tens and ones.
  • Pull off the last three digits. Spell them with the helper. Add the group name.
  • Drop those digits and move to the next group.

Why it is fast:

  • The three-digit helper is the same every time, in any group.
  • We reuse it and just add the right word after. Little repeated work.

Here is the flow of this approach.

yes

no

take last 3 digits

spell with helper

attach group name

thousand or million or billion

move to next 3 digits

more digits left?

join all parts

Steps to Solve

  1. Handle zero first. If the number is 0, return "Zero".
  2. Make a helper that spells any number from 1 to 999. It handles the hundreds part, then the tens and ones.
  3. Set up the group names: thousand, million, billion.
  4. Pull off the last three digits of the number.
  5. Spell those three digits with the helper, then add the right group name.
  6. Drop those three digits and move to the next group.
  7. Repeat until the number is gone, then join all the parts with spaces.

This Python version uses lists for the word lookups and a small recursive helper for each three-digit group.

integer_to_english_words.py
below20 = ["", "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"]
thousands = ["", "Thousand", "Million", "Billion"]
def helper(n): # spell 1 to 999
if n == 0:
return ""
if n < 20:
return below20[n] + " "
if n < 100:
return tens[n // 10] + " " + helper(n % 10)
return below20[n // 100] + " Hundred " + helper(n % 100)
def number_to_words(num):
if num == 0:
return "Zero"
result = ""
idx = 0
while num > 0:
if num % 1000 != 0: # skip empty groups
group = helper(num % 1000) # spell this 3-digit group
result = group + thousands[idx] + " " + result # add group name
num //= 1000 # drop these 3 digits
idx += 1
return " ".join(result.split()) # tidy the spaces
print(number_to_words(1234567))

The output of the above code will be:

One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven

Let us walk through the Python version line by line, because it shows the group idea clearly.

helper(n) spells any number from 1 to 999. If n is under 20, we read it straight from the below20 list, because numbers like eleven and thirteen have their own words. If n is under 100, we take the tens word and then recurse on the ones. If n is 100 or more, we take the hundreds word, add β€œHundred”, and recurse on the rest. We call helper again on the smaller part because the same spelling rule applies to it.

if num == 0: return "Zero" handles the one special case. Zero has no group, so we return its word right away.

while num > 0: is the main loop. It runs once for each three-digit group.

if num % 1000 != 0: checks the last three digits. The % 1000 gives the lowest group. We skip it if it is zero, because we do not want to print an empty group name.

result = group + thousands[idx] + " " + result builds the answer from the right side. We add new groups to the front because we read low groups first but say high groups first. The thousands[idx] picks the right name: thousand, million, or billion.

num //= 1000 drops the three digits we just used. The // is integer division, so 1234567 // 1000 becomes 1234.

return " ".join(result.split()) cleans up extra spaces. The split breaks on any whitespace and the join puts single spaces back. We do this so the final string has no double spaces.

⏱️ Time and Space Complexity

The number has a fixed limit, so it has a fixed number of groups. Each group takes a small constant amount of work. So the time is really tied to how many digits the number has. We call that O(d), where d is the digit count. The space is the size of the answer string, which is also tied to the digit count. So both stay small and grow slowly with the number.

Approach Time Complexity Space Complexity
Digit by digit (wrong) O(d) O(d)
Three-digit groups O(d) O(d)

Tip

In an interview, write the three-digit helper first and test it alone. Once it spells 1 to 999 right, the group loop is easy. Building the small piece first keeps the big problem from feeling scary.

🧩 Key Takeaways

  • βœ… Break the number into three-digit groups from the right, just like we say numbers out loud.
  • βœ… Write one helper that spells any number from 1 to 999. Reuse it for every group.
  • βœ… Attach the group name after each group: thousand, million, billion.
  • βœ… Skip a group if all three digits are zero, so you do not print an empty name.
  • βœ… Handle zero as a special case at the very start.

Check Your Knowledge

4 questions Show quiz Hide quiz

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    How does the optimal approach break the number apart?

    Why: We read numbers in three-digit groups, the same way we say them out loud.

  2. 2

    Why is reading one digit at a time wrong?

    Why: Place value matters. The digit 2 means twenty in 123 but two in 213, so single digits lose meaning.

  3. 3

    What does the helper function spell?

    Why: The helper spells any three-digit group, from 1 to 999, and we reuse it for every group.

  4. 4

    What should the function return for the input 0?

    Why: Zero is a special case handled at the start, and the function returns the word Zero.

πŸš€ What’s Next?