LeetCode题练习与总结:整数反转

158 篇文章 0 订阅
95 篇文章 0 订阅

一、题目描述

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−2^31,  2^31 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:

输入:x = 123
输出:321

示例 2:

输入:x = -123
输出:-321

示例 3:

输入:x = 120
输出:21

示例 4:

输入:x = 0
输出:0

提示:

  • -2^31 <= x <= 2^31 - 1

二、解题思路

  1. 确定反转限制: 由于题目要求反转后的整数不能超过32位有符号整数的范围(-2^31到2^31-1),我们需要在反转过程中不断检查当前的反转值是否超出这个范围。

  2. 处理符号位: 由于我们不能直接处理64位整数,我们需要在反转过程中单独处理符号位。这意味着我们需要在反转完成后,根据原始整数的符号位来确定最终结果的符号。

  3. 反转整数: 使用循环和位操作来逐位反转整数。在每次迭代中,我们从原始整数中提取最低位,将其添加到反转后的整数中,并更新原始整数。

  4. 检查范围: 在每次迭代中,我们需要检查反转后的整数是否已经超出了32位整数的范围。这可以通过比较反转后的整数与32位整数的最大值(Integer.MAX_VALUE)和最小值(Integer.MIN_VALUE)来实现。

  5. 返回结果: 如果在整个反转过程中没有超出范围,那么在循环结束后,我们可以根据原始整数的符号位来确定最终的反转结果。如果超出了范围,我们需要返回0。

  6. 编写代码: 根据上述思路,编写代码实现反转逻辑。在代码中,我们需要使用循环来处理每一位数字,同时在每一步中检查反转后的值是否合法。

这个解题思路的核心在于理解整数反转的过程,并在每一步中确保结果不会超出32位整数的范围。通过这种方式,我们可以在不使用64位整数的情况下,安全地反转32位有符号整数。

三、具体代码

class Solution {

    public int reverse(int x) {
        // 初始化反转后的数字
        int reversed = 0;
        // 初始化符号位
        int sign = (x < 0) ? -1 : 1;
        // 将x转换为正数,以便反转
        x = Math.abs(x);

        // 反转数字
        while (x > 0) {
            // 取出当前位
            int digit = x % 10;
            // 检查是否超出32位整数范围
            if (reversed > Integer.MAX_VALUE / 10 || (reversed == Integer.MAX_VALUE / 10 && digit > 0)) {
                return 0;
            }
            // 检查是否超出32位整数范围(负数情况)
            if ((reversed * 10 + digit) < 0) {
                return 0;
            }
            // 将当前位添加到反转后的数字
            reversed = reversed * 10 + digit;
            // 移除已处理的位
            x /= 10;
        }

        // 如果原始数字是负数,反转后的数字也需要是负数
        return reversed * sign;
    }
}

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

1. 时间复杂度
  • 时间复杂度:O(n)。
  • 时间复杂度主要取决于循环的次数。
  • 在最坏的情况下,我们需要处理一个32位的整数,这意味着循环将执行32次(因为每次循环处理一个数字位)。
  • 因此,时间复杂度是 O(n),其中 n 是整数的位数。在这个特定的例子中,n 最大为 32。
2. 空间复杂度
  • 空间复杂度:O(1)。
  • 空间复杂度主要考虑的是程序运行过程中所需的额外存储空间。
  • 在这个代码中,我们使用了两个变量 reversedsign 来存储反转后的数字和符号位。
  • 这些变量在整个函数执行过程中都保持不变,因此空间复杂度是 O(1),即常数空间复杂度。

这里的 n 是整数的位数,对于32位整数,n 的最大值为32。在实际应用中,这个算法对于任何长度不超过32位的整数都是有效的,因此时间复杂度和空间复杂度都是固定的。

五、总结知识点

  1. 位操作:`x % 10`:取整数的最低位(即个位);`x /= 10`:将整数除以10并向下取整,移除最低位。
  2. 数学运算:`Math.abs(x)`:获取整数的绝对值,用于处理负数。
  3. 条件判断:`if` 语句用于检查反转过程中是否超出了32位整数的范围;`&&` 和 `||` 逻辑运算符用于组合多个条件。
  4. 循环控制:`while` 循环用于逐位反转整数。
  5. 数据类型和范围检查:了解 `int` 类型在Java中的范围(-2^31 到 2^31-1);在反转过程中,需要检查反转后的数字是否超出了 `int` 类型的范围。
  6. 符号处理:使用 `sign` 变量来记录原始整数的符号,以便在反转完成后正确处理负数。
  7. 边界条件处理:在反转过程中,需要处理边界条件,例如当反转后的数字接近 `Integer.MAX_VALUE` 或 `Integer.MIN_VALUE` 时,需要特别小心,以避免溢出。
  8. 代码风格和可读性:代码中的注释有助于理解逻辑流程;使用变量名如 `reversed` 和 `sign` 来提高代码的可读性。
  9. 错误处理:当反转后的数字超出范围时,代码返回0,这是一种错误处理机制。
  10. 算法效率:代码尽可能地避免了不必要的计算,例如在检查是否超出范围时,只检查了必要的条件。

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

  • 32
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一直学习永不止步

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

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

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

打赏作者

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

抵扣说明:

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

余额充值