LeetCode题练习与总结:整数转换英文表示--273

227 篇文章 0 订阅
40 篇文章 0 订阅

一、题目描述

将非负整数 num 转换为其对应的英文表示。

示例 1:

输入:num = 123
输出:"One Hundred Twenty Three"

示例 2:

输入:num = 12345
输出:"Twelve Thousand Three Hundred Forty Five"

示例 3:

输入:num = 1234567
输出:"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"

提示:

  • 0 <= num <= 2^31 - 1

二、解题思路

  1. 首先定义小于20的数字和10的倍数的英文表示,因为它们的表示是特殊的(例如,10是"Ten",11是"Eleven")。
  2. 定义一个方法,用于处理小于1000的数字,因为这个范围内的数字表示有一定的规律性(例如,123是"One Hundred Twenty Three")。
  3. 由于英文数字表示中,每三位数就会有一个单位(例如,“Billion”, “Million”, “Thousand”),我们可以按照每三位一组的方式,将数字拆分成多个小组。
  4. 对于每个小组,使用步骤2定义的方法来转换成英文表示,并加上对应的单位。
  5. 将所有小组的英文表示拼接起来,得到最终结果。

三、具体代码

class Solution {
    private static 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 static final String[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    private static final String[] THOUSANDS = {"", "Thousand", "Million", "Billion"};

    public String numberToWords(int num) {
        if (num == 0) return "Zero";
        StringBuilder sb = new StringBuilder();
        for (int i = 3, unit = 1000000000; i >= 0; i--, unit /= 1000) {
            int curNum = num / unit;
            if (curNum != 0) {
                num -= curNum * unit;
                sb.append(helper(curNum)).append(THOUSANDS[i]).append(" ");
            }
        }
        return sb.toString().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);
        }
    }
}

在这段代码中,numberToWords 方法负责将数字拆分成多个三位数的组,并调用 helper 方法将每个组转换成英文表示。helper 方法则根据数字的大小,递归地将其转换成英文表示。

四、时间复杂度和空间复杂度

1. 时间复杂度
  • numberToWords 方法中有一个for循环,该循环会最多执行4次(对应于" Billion", “Million”, “Thousand”, "None"这些单位)。每次循环中,都会调用 helper 方法。
  • helper 方法是一个递归方法,但是它的递归深度最多为3(对于小于1000的数字,递归会停在个位数上)。这是因为每次递归都会将数字缩小到原来的1/10或者1/100。
  • 因此,helper 方法的调用次数是常数次的(最多3次)。
  • 综上所述,时间复杂度是O(1),即常数时间复杂度。尽管我们有一个循环,但由于循环次数和递归深度都是固定的,因此总体的操作次数是有限的,不随输入数字的大小而变化。
2. 空间复杂度
  • LESS_THAN_20TENSTHOUSANDS 这三个字符串数组占用的空间是固定的,不随输入数字的大小而变化。
  • numberToWords 方法中使用了 StringBuilder 来构建结果字符串。在最坏的情况下,即数字接近2^31 - 1时,StringBuilder 的长度可能会达到几十个字符,但这也是一个常数级别的空间。
  • helper 方法是递归调用的,每次递归调用都会在调用栈上占用一定的空间。由于递归深度最多为3,因此调用栈的空间占用也是常数级别的。
  • 综上所述,空间复杂度是O(1),即常数空间复杂度。尽管使用了递归,但由于递归深度固定,因此总体的空间占用是有限的,不随输入数字的大小而变化。

五、总结知识点

  1. 静态常量数组LESS_THAN_20TENSTHOUSANDS 是静态常量数组,用于存储数字的英文表示。它们在类加载时初始化,并在整个程序运行期间保持不变。

  2. 递归方法helper 方法是一个递归方法,它用于将小于1000的数字转换成英文表示。递归方法在解决能够分解成更小相似问题的场景中非常有用。

  3. 字符串拼接:在 helper 方法中,字符串是通过 + 运算符拼接的。这是处理字符串常用的方法之一。

  4. StringBuilder 类:在 numberToWords 方法中,使用了 StringBuilder 类来构建最终的英文数字表示。StringBuilder 在处理频繁修改字符串的场景中比直接使用字符串拼接更高效。

  5. 数学运算:代码中使用了整数除法和取余操作来将数字拆分成不同的部分(如百位、十位、个位)。

  6. 循环控制numberToWords 方法中使用了一个for循环来处理数字的每个千位分组(Billion, Million, Thousand, None)。循环中的 i 变量用来索引 THOUSANDS 数组,而 unit 变量用来确定当前处理的千位分组的大小。

  7. 条件语句:在 helper 方法中,使用了if-else语句来根据数字的大小选择不同的处理逻辑。

  8. 字符串处理:在返回结果之前,使用了 trim() 方法来移除字符串末尾的空格。

  9. 边界条件处理:在 numberToWords 方法开始时,如果输入数字为0,则直接返回 “Zero”,这是对特殊情况的处理。

  10. 模块化设计:代码被设计成模块化的,helper 方法负责处理小于1000的数字,而 numberToWords 方法则负责处理更大范围的数字,这种设计使得代码易于理解和维护。

  11. 面向对象编程:整个解决方案被封装在一个 Solution 类中,这是一种面向对象编程的实践,有助于代码的组织和重用。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值