【leetcode】js实现整数反转

747 阅读3分钟

题目:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

输入: 123
输出: 321

示例 2:

输入: -123
输出: -321

示例 3:

输入: 120
输出: 21

注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

刚拿到题目,第一反应是拆成数组,用数组的reverse方法,然后join,so easy。很快码出了代码:

var reverse = function(x) {
    if (isNaN(x) || x == 0) return 0;
    x = x + '';
    let nums = x.split('');
    let nagtive = false;
    if (nums[0] + '' == '-') {
        nagtive = true;
        nums.shift(0);
    };
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            break;
        }
        nums.shift(0);
    }
    return (nagtive ? '-' : '') + nums.reverse().join('');
};

Test也没问题输入123返回321,然而Submit 的时候问题来了 :

又仔细看了下题目——32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]

加个范围的事,于是改了一下:

var reverse = function(x) {
    if (isNaN(x) || x == 0) return 0;
    if (x > 2147483648 || x < -2147483648) return 0; // 加了这一行
    x = x + '';
    let nums = x.split('');
    let nagtive = false;
    if (nums[0] + '' == '-') {
        nagtive = true;
        nums.shift(0);
    };
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            break;
        }
        nums.shift(0);
    }
    return (nagtive ? '-' : '') + nums.reverse().join('');
};

但是依然是 Test 通过,Submit 不通过,错误 case 和之前一样。原来是结果值超出了32位有符号整数范围。继续修改:

var reverse = function(x) {
    if (isNaN(x) || x == 0) return 0;
    if (x > 2147483648 || x < -2147483648) return 0; // 加了这一行
    x = x + '';
    let nums = x.split('');
    let nagtive = false;
    if (nums[0] + '' == '-') {
        nagtive = true;
        nums.shift(0);
    };
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            break;
        }
        nums.shift(0);
    }
    
    // 以下代码做了修改
    let result = parseInt((nagtive ? '-' : '') + nums.reverse().join(''));
    if (result > 2147483648 || result < -2147483648) return 0;
    return result;
};

这次 Test 和 Submit。

到这里我已经感觉到写的不够优雅,与leetcode格格不入了。同时这段代码被一个Java同事看到了,他指着nums.reverse()方法问我:“这是系统的方法吗?”我说:“是的。”——“那你这道题得零分啊!”

。。。

反思了一会看了答案,根本不是什么又reverse又join,而是逐次的拿掉最后一位数,然后拼成一个反转后的整数,代码如下:

var mod = x % 10 // 取出末位
var s = x / 10 | 0 // 去掉末位(取整)
var re = 0
while(s || mod) {
    if(re > 214748364 || re == 214748364 && mod > 7 || re < -214748364 || re == -214748364 && mod < -8) return 0 // 判断溢出
    re = re * 10 + mod // 末位放到头位
    mod = s % 10 // 继续取出末位
    s =  s / 10 | 0 // 继续去掉末位,然后循环
}
return re

羞愧难当,用系统的reverse方法去实现反转,相当于用海参炒面换汤面,完了还不给钱。