给你一个 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

 

提示:

  • -231 <= x <= 231 - 1
Related Topics
  • 数学

  • 👍 3012
  • 👎 0
  • 题解

    简单题,最直接的思路就是翻转了,但是还有个符号位,所以符号位的逻辑要额外处理下。刷题刷得可嗨了……被同事看到了,然后他也想试试,emm过了半天跑来问我这题。顺手写下再给他讲下。

    /**
     * 字符串拼接转换,性能较低
     * 解答成功:
     * 执行耗时:3 ms,击败了16.46% 的Java用户
     * 内存消耗:35.7 MB,击败了19.93% 的Java用户
     * @param x
     * @return
     */
    public int reverse(int x) {
        String str = Integer.toString(x);
        char[] arr = str.toCharArray();
        int left = 0;
        int right = arr.length-1;
        if (arr[0]=='-'){
            left=1;
        }
        char tmp;
        while (left<right){
            tmp = arr[left];
            arr[left]=arr[right];
            arr[right]=tmp;
            left++;
            right--;
        }
        String newStr = new String(arr);
        int newInt;
        try {
            newInt = Integer.parseInt(newStr);
        }catch (NumberFormatException e){
            //用了异常来实现逻辑、这种方法在实际编码中绝对绝对不可取
            return 0;
        }
        return newInt;
    }

    但是这边用了个try/catch来处理异常来实现逻辑上的处理,这种处理办法应该是绝对禁止的,非常不符合代码规范。而且try/catch带来的性能损失应该也是不小的。

    所以,更好的办法如下:

    /**
     * 数学计算绝对不溢出方法
     * 解答成功:
     * 执行耗时:1 ms,击败了100.00% 的Java用户
     * 内存消耗:35.6 MB,击败了39.89% 的Java用户
     *
     * @param x
     * @return
     */
    public int reverse2(int x) {
        String str = Integer.toString(x);
        char[] arr = str.toCharArray();
        x = 1;
        int limit = 0;
        if (arr[0]=='-'){
            x = -1;
            limit = 1;
            arr[0] = '0';
        }
        int num = 0;
        for (int i = str.length()-1; i >= limit; i--) {
            num = num*10 + (arr[i]-'0');
            if (i==limit+1){
                if (Integer.MAX_VALUE/10 <num || (Integer.MAX_VALUE/10 == num*10 && Integer.MAX_VALUE%10 < (arr[limit]-'0'))){
                    return 0;
                }
            }
        }
        return x*num;
    }

    这边溢出判断用了Integer.MAX_VALUE/10来处理,这样能有效避免溢出的问题。另外也有想过溢出后正负数相乘应该为负数这种方法来判断,但是实际数据表明……..乘以10之后溢出的话,仍然可能还为正数,指多绕了几圈又绕回正数区间了,然后再相乘的话是一个更加更加大的数值,依然可能为正数,所以这种判断方式不可取。必须老老实实用Integer.MAX_VALUE/10和还没乘以10进位的数字大小做比较。

    顺便,评论区有个这么一个答题内容

        public int reverse(int x) {
            long n = 0;
            while(x != 0) {
                n = n*10 + x%10;
                x = x/10;
            }
            return (int)n==n? (int)n:0;
        }

    一眼看到好惊艳,但是再看下其实不对劲。关键在这里

    long n = 0;

    long类型变量的存在就忽略了题中要求的“假设环境不允许存储 64 位整数(有符号或无符号)。”