Intuition
Split the number into 3-digit groups from the right. Spell each group (hundreds/tens/ones) and append its scale word — Thousand, Million, Billion.
Explanation
Group by thousands
English names numbers in 3-digit groups. Peel off num % 1000 at a time; spell that group with a helper (X Hundred Y Z), append the scale word for its position (Thousand / Million / Billion), and prepend to the result. Zero groups are skipped.
helper(n): words for a value < 1000
while num: chunk = helper(num%1000) + scale[i]; prepend; num //= 1000; i++
Worked example
1234567 → One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven.
Complexity
- Time: O(1) (at most 10 digits).
- Space: O(1).
Implementation
import java.util.ArrayList;
import java.util.List;
class Solution {
private String[] below20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"};
private String[] tens = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
private String[] thousands = {"", "Thousand", "Million", "Billion"};
public String numberToWords(int num) {
if (num == 0) return "Zero";
List<String> res = new ArrayList<>();
int i = 0;
while (num > 0) {
if (num % 1000 != 0) {
List<String> chunk = helper(num % 1000);
if (!thousands[i].isEmpty()) chunk.add(thousands[i]);
res.addAll(0, chunk);
}
num /= 1000;
i++;
}
return String.join(" ", res);
}
private List<String> helper(int n) {
List<String> r = new ArrayList<>();
if (n == 0) return r;
if (n < 20) {
r.add(below20[n]);
} else if (n < 100) {
r.add(tens[n / 10]);
r.addAll(helper(n % 10));
} else {
r.add(below20[n / 100]);
r.add("Hundred");
r.addAll(helper(n % 100));
}
return r;
}
}