题目难度: 困难
原题链接
今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~
给定一个整数,打印该整数的英文描述。
O(1)
: 只遍历了常数长度的数字O(1)
: 只使用了几个常数空间的变量class Solution:
def numberToWords(self, num: int) -> str:
# maps存储数字和对应单词的映射关系, 注意10~19以及20~90的映射
maps = {0: "Zero", 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"}
# units存储千位单位
units = [[], ["Thousand"], ["Million"], ["Billion"]]
if num == 0:
# 单独0, 直接返回Zero, 其他情况下都不会输出Zero
return maps[0]
def convertToList(num, ui):
# 独立方法, 将一组三位数字转成对应的英文表示, 并加上相应千位单位
if num == 0:
# 注意如果num是0的话直接返回空, 不管ui是什么, 否则1000000会被转换成One Million Thousand
return []
# 先转成[百,十,个]数组
nums = [num // 100 % 10, num // 10 % 10, num % 10]
res = []
for i, x in enumerate(nums):
if x == 0:
# 遇到0, 直接跳过
continue
if i == 1:
# 当前是十位
if x == 1:
# 10~19, 合并当前位和下一位的数字, 使用Ten到Nineteen, 退出循环
res.append(maps[x * 10 + nums[i + 1]])
break
else:
# 20+, 使用Twenty到Ninety
res.append(maps[x * 10])
else:
# 百位和个位都直接使用单个单词
res.append(maps[x])
if i == 0:
# 百位, 需要额外加上Hundred
res.append("Hundred")
# 注意额外加上当前的千位单位
return res + units[ui]
# i是当前的位数下标
i = 0
# ui是当前的千位单位下标, 第一组是空, 第二组是Thousand, 第三组是Million, 依此类推
ui = 0
# cur保存当前处理的数字
cur = 0
res = []
while num:
# 将当前数字累加到cur
cur += (num % 10) * (10 ** (i % 3))
num //= 10
i += 1
if i % 3 == 0:
# 此时达到分界点, 将当前的三位数字作为一组, 转换成字符串
res = convertToList(cur, ui) + res
# 注意更新千位单位下标和cur
ui += 1
cur = 0
# 注意循环结束时cur有可能不是0, 但是没达到3位, 也需要转成字符串
res = convertToList(cur, ui) + res
# 将字符串数组中间加上空格, 即为最终结果
return " ".join(res)
大家可以在下面这些地方找到我~
我的 GitHub
我的 Leetcode
我的 CSDN
我的知乎专栏
我的头条号
我的牛客网博客
我的公众号: 算法精选, 欢迎大家扫码关注~