LeetCode-7 整数反转 难度中等

83 阅读2分钟

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

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 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

看到这个题的时候,大家第一时间想到的可能是以下的第一种实现方式:

/**
 * @param {number} x
 * @return {number}
 */
const reverse = function (x) {
    let s = x.toString();
    let negative = s.startsWith('-');
    s = negative ? s.substring(1, s.length) : s;
    s = s.split('').reverse().join('');
    let num = negative ? -(parseInt(s)) : parseInt(s);
    if (num >= Math.pow(2, 31) - 1 || num <= Math.pow(-2, 31)) {
        return 0;
    }
    return num;
};

这种实现方式虽然好,转字符串非常占用内存,而且还解决不了不能存储64位整数这个问题,假设这个数就是一个64位整数,当执行到parseInt的时候就开始报错了,因此我们想到了另外一个方案,我们每次取一位数然后校验是否超出存储范围,以下是代码实现方式:

/**
 * @param {number} x
 * @return {number}
 */
const reverse = function (x) {
    // 提前计算出数据范围
    let max = Math.pow(2, 31) - 1;
    let min = Math.pow(-2, 31);
    // 初始化反转的数字
    let rev = 0;
    // 只要x不为0,则循环继续
    while (x) {
        // 每次将之前反转的数字乘以10,再取出剩余末尾一位数字,将两者相加
        rev = rev * 10 + x % 10;
        // 这里使用取证,当大于0和小于0的时向下取整的方式不一样,这里很有意思,建议大家试一试
        x = x > 0 ? Math.floor(x / 10) : Math.ceil(x / 10);
        // 判断是否超出数据范围
        if (rev >= max || rev <= min) {
            return 0;
        }
    }
    return rev;
};