Sunday, May 29, 2016

[LeetCode] Integer to English Words

Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1.
For example,

123 -> "One Hundred Twenty Three"
12345 -> "Twelve Thousand Three Hundred Forty Five"
1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"

There are several key observations to solve this:
1. the number can be divided into numbers of 3 digits long;
2. for every 3 digits, words like ""Thousand", "Millions", "Billion" are added
3. if the last two digits of the 3 digits form a number falls between 10 to 19, we treat them together; otherwise we treat them separately.
4. read the digits from left to right until we process all digits

Here is the source code:
public String numberToWords(int num) {
if(num==0)
return "Zero";
Map<Integer, String> map = new HashMap<>();
map.put(3, "Thousand");
map.put(6, "Million");
map.put(9, "Billion");
String[] store = new String[]{"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
String[] store1 = new String[]{"Ten","Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
String[] store2 = new String[]{"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
//pointer starts from the right and move to the left
int index = 0;
//stack to store the words
Stack<String> stack = new Stack<>();
while(num>0){
//store thousand, million or billion only there is digits in last 3
if(index%3==0 && index>0 && num%1000>0){
stack.push(map.get(index));
}
if(index%3==0){
//if the last digits fall into [10 - 19]
if(num%100>9 && num%100<20){
stack.push(store1[num%10]);
index++;
num /=10;
}else{
if(num%10>0){
stack.push(store[num%10]);
}
}
}else if(index%3==1){
if(num%10>1){
stack.push(store2[num%10]);
}
}else{
if(num%10>0){
stack.push("Hundred");
stack.push(store[num%10]);
}
}
//move the pointer to left
index++;
//chop the last digit
num /= 10;
}
StringBuilder sb = new StringBuilder();
while(!stack.empty()){
sb.append(stack.pop());
sb.append(" ");
}
return sb.toString().trim();
}