My clean Java solution, very easy to understand


  • 192
    H
    private final String[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
    private final String[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    private final String[] THOUSANDS = {"", "Thousand", "Million", "Billion"};
    
    public String numberToWords(int num) {
        if (num == 0) return "Zero";
    
        int i = 0;
        String words = "";
        
        while (num > 0) {
            if (num % 1000 != 0)
        	    words = helper(num % 1000) +THOUSANDS[i] + " " + words;
        	num /= 1000;
        	i++;
        }
        
        return words.trim();
    }
    
    private String helper(int num) {
        if (num == 0)
            return "";
        else if (num < 20)
            return LESS_THAN_20[num] + " ";
        else if (num < 100)
            return TENS[num / 10] + " " + helper(num % 10);
        else
            return LESS_THAN_20[num / 100] + " Hundred " + helper(num % 100);
    }

  • 0
    W

    you can combine ones and lesThan20 into one array and get rid of one branch in your helper function


  • 0
    H

    Good suggestion!!! I've changed it. Thank you very much!!!


  • 0
    M

    Run Time 72 ms


  • 0
    S
    This post is deleted!

  • 0
    H

    Since this problem asks us to convert a "non-negative" integer into its English words representation, we don't need to consider negative cases.


  • 15
    U
    public class Solution {
    public String numberToWords(int num) {
        if (num == 0) return "Zero";
        String[] lessThan20Words = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
        String[] tyWords = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
        String[] dexWords = {"Billion", "Million", "Thousand", "Hundred"};
        int[] radix = {1000000000,1000000, 1000, 100};
        StringBuffer sb = new StringBuffer();
        int count = 0;
        for (int i = 0; i < radix.length; ++i) {
            count = num / radix[i];
            if (count == 0) continue;
            sb.append(numberToWords(count) + " ");
            sb.append(dexWords[i] + " ");
            num %= radix[i];
        }
        if (num < 20) {
            sb.append(lessThan20Words[num]);
        }else {
            sb.append(tyWords[num / 10 - 2] + " ");
            sb.append(lessThan20Words[num % 10]);
        }
        return sb.toString().trim();
    }
    

    }


  • 2
    V

    I believe this would return "" for num = 1000?


  • 5
    A

    I tried to combine the two solutions here and came up with my version, just to provide some additional thought. Thank you for the previous two great methods.

    final String[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
    final String[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    final String[] THOUSANDS = {"Billion", "Million", "Thousand", ""};
    final int[] radix = {1000000000, 1000000, 1000, 1};
    
    public String numberToWords(int num) {
        if (num == 0) return "Zero";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < radix.length; i++) {
            if (num / radix[i] == 0) continue;
            sb.append(trans(num / radix[i])).append(THOUSANDS[i]).append(' ');
            num %= radix[i];
        }
        return sb.toString().trim();
    }
    
    private String trans(int num) {
        if (num == 0) return "";
        if (num < 20) return LESS_THAN_20[num] + " ";
        if (num < 100) return TENS[num / 10] + " " + trans(num % 10);
        return LESS_THAN_20[num / 100] + " Hundred " + trans(num % 100);
    }

  • 0
    Y

    Can anyone explain how to realize trim() in C++?


  • 1

    @hwy_2015 Hi, Thank your clean solution. I wrote a C++ recursive version based on your clear code.
    @Yan_Sylvia_Liu Hi, you can use find_first_not_of(' ') and find_last_not_of(' ') in C++ to implement trim() in java

    private:
        string LESS20[20] = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",                                "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
        string TENS[10] = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
        string THOUSANDS[4] = {"", "Thousand", "Million", "Billion"};
    public:
        string Less1000(int num)
        {
            if(num==0) return "";
            if(num<20) return  LESS20[num] + " ";
            if(num<100) return TENS[num/10] + " " + Less1000(num%10);
            return LESS20[num/100] + " Hundred "  + Less1000(num%100);
        }
        string numberToString(int num, int i)
        {
            if(num==0) return "";
            if(num%1000==0) return numberToString(num/1000, i+1);
            return numberToString(num/1000, i+1) + Less1000(num%1000)  + THOUSANDS[i] + " ";
        }
        string numberToWords(int num) {
            if(num==0) return "Zero";
            string res = numberToString(num, 0);
            return res.substr(0, res.find_last_not_of(' ')+1);
        }
    

  • 0

    Nice solution. Using StringBuilder instead of String can be faster and consuming less memory.


  • 0
    K

    @uucoder awesome solution....I love it. Way better and faster than original one posted earlier....


  • 0
    R

    This solution is brilliant!


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.