Integer to English Words

Hard
1251.

Integer to English Words

Integer to English Words is a hard coding problem on strings, math and recursion, asked in Amazon, Microsoft, Meta and Yahoo interviews.

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
Write your solution here. Running it against the tests needs a free account — what you type comes with you.Sign in to run
/**
 * @param {number} num
 * @return {string}
 */
var numberToWords = function(num) {
    // Write your code here
    
};

Sign in to run your own test cases

Sign in

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.

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

  1. Hint 1

    Split the number into groups of three digits from the right: billions, millions, thousands and units.

  2. 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.

  3. 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-case num == 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

  1. If num == 0, return Zero.
  2. Keep tables for 1–19 (One…Nineteen) and for the tens (Twenty…Ninety).
  3. To name g < 1000: if g >= 100 emit the hundreds digit and Hundred; then for the remaining r = g % 100, emit TENS[r / 10] if r >= 20 and then the unit word if any, or the 1–19 word directly.
  4. Walk the groups from the billions down: g = (num / scale) % 1000. If g > 0, emit its name followed by the scale word (none for the units group).
  5. 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 Zero for an empty group or an empty units part, or leaving double spaces where a part is missing.
  • Numbers 10–19 are single words (Eleven, not Ten One).
  • Forty is 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.

All 515 strings problems · the whole catalogue

Learn the technique: Strings · Recursion