LeetCode 273 Integer to English Words
Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1.
Example 1:
**Input:** 123
**Output:** "One Hundred Twenty Three"
Example 2:
**Input:** 12345
**Output:** "Twelve Thousand Three Hundred Forty Five"
Example 3:
**Input:** 1234567
**Output:** "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
Example 4:
**Input:** 1234567891
**Output:** "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One"
题目大意:
这是将非负整数转化为其英文单词表示。给定输入确保小于 2 ^ 31 - 1
解题思路(推荐):
第二种方法是按千位递归的。下面的方法是按20以下,100以下,百位,千位…递归,递归的颗粒度更小,程序更简单。
注意事项:
- 在入口方法中,若num为0,则返回Zero,要单独列出。
- 在递归中,num为0要单独列出,因为0表示此位不存在,可以记在dict中或返回空字符串。
- strip来去掉空格。
Python代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| NUM_DICT = { 0: '', 1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven', 8: 'Eight', 9: 'Nine', 10: 'Ten', 11: 'Eleven', 12: 'Twelve', 13: 'Thirteen', 14: 'Fourteen', 15: 'Fifteen', 16: 'Sixteen', 17: 'Seventeen', 18: 'Eighteen', 19: 'Nineteen', 20: 'Twenty', 30: 'Thirty', 40: 'Forty', 50: 'Fifty', 60: 'Sixty', 70: 'Seventy', 80: 'Eighty', 90: 'Ninety', } class Solution(TestCases):
def numberToWords(self, num: int) -> str: if num == 0: return 'Zero' return self.dfs(num)
def dfs(self, num: int) -> str: if num < 20: return NUM_DICT[num] elif num < 100: return (NUM_DICT[num // 10 * 10] + ' ' + self.dfs(num % 10)).strip() elif num < 1000: return (NUM_DICT[num // 100] + ' Hundred ' + self.dfs(num % 100)).strip() elif num < 1000000: return (self.dfs(num // 1000) + ' Thousand ' + self.dfs(num % 1000)).strip() elif num < 1000000000: return (self.dfs(num // 1000000) + ' Million ' + self.dfs(num % 1000000)).strip() elif num < 1000000000000: return (self.dfs(num // 1000000000) + ' Billion ' + self.dfs(num % 1000000000)).strip() return ''
|
注意事项:
- 空格总加在新数前面,只需要加在有返回值的时候,也就是tens和lows中,其他如numberToWordsR(number/1000)
可能返回空值,此时不在前面加空格。
- 在递归中,num为0要单独列出,因为0表示此位不存在,也就是无返回值。
- 在入口方法中,若num为0,则返回Zero,要单独列出。
Java代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public String numberToWords(int number) { if (number == 0) return "Zero"; return numberToWordsR(number).trim(); }
public String numberToWordsR(int number) { if(number == 0) { return ""; } else if (number < 20) { return " " + lows[number]; } else if (number < 100) { return " " + tens[number / 10] + numberToWordsR(number % 10); } else if (number < 1000) { return " " + lows[number / 100] + " Hundred" + numberToWordsR(number % 100); } else if (number < 1000000) { return numberToWordsR(number / 1000) + " Thousand" + numberToWordsR(number % 1000); } else if (number < 1000000000) { return numberToWordsR(number / 1000000) + " Million" + numberToWordsR(number % 1000000); } else { return numberToWordsR(number / 1000000000) + " Billion" + numberToWordsR(number % 1000000000); } }
|
算法II每三位解题思路:
这是logical and maintainable的经典题。按照英语的习惯,每三位是一组,所以实现的时候,也是按千为分组,有一个方法去处理一千
内的数。一千以内也分为三种情况,20以内,几十,其他。20以内和几十都是特殊情况的单词,所以可以放入数组或HashMap,数组比较
好,因为可以直接用索引读出。大于一千的数,可以用递归来做,从人的习惯,从低位到高位,每三位加一个逗号分隔。所以同样,算法
也是从低位开始,若千位内的数大于0,加入Thousand, Million等,每三位调用千位方法,再递归。
group的引入作为递归的层次来决定Thousand还是Million。
由于从低位递归,所以倒着做,要reverse地加入到结果,最终结果再reverse回来。
注意事项:
- 空格总加在新数前面,也就是append前先加空格
- 低3位大于0才加Thousand, Million等词,也就是低三位在1-999之间,若为0如1 million。
Java代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| public String[] lows = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve","Thirteen", "Fourteen","Fifteen","Sixteen","Seventeen","Eighteen", "Nineteen"};
public String[] tens = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
public String numberToWords(int number) { if(number == 0) { return "Zero"; }
StringBuilder result = new StringBuilder();
translateThreeR(number, result, 0); return result.reverse().toString().trim(); }
public void translateThreeR(int number, StringBuilder result, int group) { int lower = number % 1000; int thousands = number / 1000;
if (group == 1 && lower > 0) result.append(reverse(" Thousand")); else if (group==2 && lower > 0) result.append(reverse(" Million")); else if (group==3 && lower > 0) result.append(reverse(" Billion")); if(lower>0) result.append(reverse(translateThree(lower))); if(thousands >= 1) { translateThreeR(thousands, result, ++group); }
}
public String translateThree(int number) { StringBuilder result = new StringBuilder(); if(number > 99) { result.append(" "+lows[number / 100]); result.append(" Hundred"); number = number % 100; }
if(number > 19) { result.append(" "); result.append(tens[number/10]); number = number % 10; }
result.append(" "+lows[number]); return " "+result.toString().trim(); }
public String reverse(String s) { return (new StringBuilder()).append(s).reverse().toString(); }
|
算法分析:
n为位数,时间复杂度为O(n),空间复杂度O(1)。
Follow-up:
integer, minus, decimals, internationlization(localization)。