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(" ")
Difficulty
and has an acceptance rate of about 35% (1+ million submissions).
Typical patterns to solve this problem:
- Math
- Recursion
- String
AI Disclaimer
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.
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.
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.
Code Quality
Complexity Analysis
Other Solutions
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++ |
Videos
Similar Problems
- problem 12: Integer to Roman
Solved On The Same Day
- problem 417: Pacific Atlantic Water Flow
- problem 442: Find All Duplicates in an Array
- problem 457: Circular Array Loop
- problem 554: Brick Wall
- problem 565: Array Nesting
- problem 647: Palindromic Substrings
- problem 721: Accounts Merge
- problem 785: Is Graph Bipartite?
- problem 1061: Lexicographically Smallest Equivalent String
Extra
- 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