Problem 273

Abstract / Summary

Convert a non negative integer to its english words representation without using special characters or abbreviations.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 0273.py

class Solution:
    def numberToWords(self, num: int) -> str:
        def one(n):
            names = [ "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" ]
            return names[n]

        def two(n):
            if n < 10:
                return one(n)

            if n < 20:
                teens = [ "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen",
                          "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" ]
                return teens[n - 10]

            tens = [ "", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" ]
            return tens[n // 10] + " " + one(n % 10)

        def three(n):
            if n < 100:
                return two(n)

            return one(n // 100) + " Hundred " + two(n % 100)


        if num == 0:
            return "Zero"

        illion = [ "", " Thousand ", " Million ", " Billion ", " Trillion ", " Gazillion " ]
        result = ""
        while num > 0:
            if num % 1000 > 0:
                result = three(num % 1000) + illion[0] + result
            num //= 1000
            illion.pop(0)

        return result.replace("  ", " ").strip(" ")
37 lines | 1234 bytes | submitted October 5, 2023 | GitHub   tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 35% (1+ million submissions).

Typical patterns to solve this problem:
  • Math
  • Recursion
  • String
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.

See this dedicated page for more details.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The provided implementation converts a non-negative integer into its English words representation. The algorithm breaks the number into groups of three digits, processes each group with helper functions, and assembles the final phrase using scale words such as “Thousand”, “Million”, etc. The code handles the special case of zero explicitly and trims excess whitespace before returning the result.

Key Steps

The conversion logic is organized around three nested helper functions that each handle a specific digit range.

Single-digit conversion

def one(n):
    names = [ "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" ]
    return names[n]

This function maps values 0-9 to their word equivalents, with an empty string for zero because zero is handled separately at the top level.

Two-digit conversion

def two(n):
    if n < 10:
        return one(n)

    if n < 20:
        teens = [ "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen",
                  "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" ]
        return teens[n - 10]

    tens = [ "", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" ]
    return tens[n // 10] + " " + one(n % 10)

The function first delegates to one for numbers below ten. For the teen range (10-19) it uses a dedicated list to return the correct word. For all other two-digit numbers it combines the appropriate tens word with the result of one for the units digit, inserting a space between them.

Three-digit conversion

def three(n):
    if n < 100:
        return two(n)

    return one(n // 100) + " Hundred " + two(n % 100)

Numbers below one hundred are passed directly to two. For values 100-999 the function constructs the “X Hundred Y” pattern, where X is obtained from one and Y from two.

Main assembly loop

if num == 0:
    return "Zero"

illion = [ "", " Thousand ", " Million ", " Billion ", " Trillion ", " Gazillion " ]
result = ""
while num > 0:
    if num % 1000 > 0:
        result = three(num % 1000) + illion[0] + result
    num //= 1000
    illion.pop(0)

return result.replace("  ", " ").strip(" ")

The loop extracts the lowest three-digit block (num % 1000) and, if non-zero, converts it with three and prefixes the appropriate scale word from illion. After processing a block, the number is divided by 1000 to move to the next higher block, and the first element of illion is removed so that the next iteration uses the next scale word. The final string is cleaned by collapsing double spaces and trimming leading/trailing spaces.

Edge Cases Handled

The code explicitly returns “Zero” when the input is exactly zero, bypassing the block-processing loop. Within two, the teen range (10-19) is treated separately to avoid incorrect composition such as “Ten One”. The three function checks for numbers below one hundred, ensuring that a trailing “Hundred” is not added when the hundreds digit is zero. The main loop skips any three-digit block that evaluates to zero, preventing unnecessary scale words like “Thousand” from appearing in the output for numbers such as 1,000,001 where the middle block is zero.

Whitespace handling at the end of the function removes any accidental double spaces that can arise from concatenating empty strings (for example, when the units digit is zero) and strips any leading or trailing spaces, guaranteeing a clean result.

Performance Optimizations

The algorithm processes the number in fixed-size chunks of three digits, which limits the number of iterations to the number of scale groups needed for the input size. By using integer division and modulo operations, the code avoids string conversions during the main loop, keeping the per-iteration work constant. The illion list is mutated with pop(0) rather than indexing with a separate counter, which eliminates the need for an additional variable to track the current scale. The final replace call collapses any double spaces in a single pass, avoiding multiple passes over the string. Overall, the design ensures that the amount of work grows linearly with the number of three-digit groups, providing efficient handling even for very large integers within the supported range.

written by openai gpt

ELI5 - Simplified Explanation

Imagine this code is like a clever robot building set that helps turn numbers into words so we can read them aloud. When you give the robot a big number, it breaks that number into tiny, bite-sized pieces of three digits each.

There is a small helper part called one that knows how to say single numbers like one, two, or three. Then there is a larger helper part called two that handles numbers up to ninety-nine, and another helper called three that works with hundreds.

Because numbers can get very large, the robot keeps track of what kind of group it is looking at, like thousands, millions, or billions. It works from the back of the number to the front, taking three digits at a time and turning them into words. Each time it finishes a small chunk, it adds the right name, like thousand or million, so everything is sorted in order.

Think of it like sorting building blocks into colored buckets. As the robot finishes each bucket, it puts the name of the bucket next to the words it just made. Finally, it cleans up any extra spaces left behind so the sentence looks perfect for reading.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 26 | median = 7 | μ = 6.12 | σ = 1.45

Complexity Analysis

not analyzed yet

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
Obviously, I did that after I solved the problem myself.

In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.

And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.

(click on a column header to sort the table)
author
author solutions
www AlgoMonster C++ Java Python TS
WalkCCC C++ Java Python
leetcode.ca C++ Java JS C# Python Go TS
LeetcodeHelp C++ Java Python
MemoryLimitExceeded C++ Python
Progiez C++ Java Python
github aylei Rust
BigEggStudy C#
black-shadows C++
charles-wangkai Java
chenyanzhe C++
everthis JS
fengvyi C++
haoel C++
JoshCrozier JS
keineahnung2345 C++
linouk23 C++
qiyuangong Java
ruoru Rust
suxrobGM C#
trung-hn Python
varunu28 Java
vli02 C
withaarzoo C++
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C++, C#, Go, Java, JavaScript, Python, TypeScript
LeetcodeHelp C++, Java, Python
MemoryLimitExceeded Python, C++
Progiez C++, Java, Python
aylei Rust
BigEggStudy C#
black-shadows C++, C++
charles-wangkai Java
chenyanzhe C++
everthis JavaScript
fengvyi C++
haoel C++
JoshCrozier JavaScript
keineahnung2345 C++
linouk23 C++
qiyuangong Java
ruoru Rust
suxrobGM C#
trung-hn Python
varunu28 Java
vli02 C
withaarzoo C++
40 links | 24 authors | 9 languages

Videos

16 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

1 similar problem

Solved On The Same Day

9 medium
10 solutions   October 5, 2023

Extra

There are a few extra pages giving you some insights into my setup:
  • Tech Stack - my development environment and tools
  • AI - how AI helped me create this website (NOT solving the problems)
  • Progress - progression over time
  • Quality - code quality