整数反转

113 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

前言

笔者除了大学时期选修过《算法设计与分析》和《数据结构》还是浑浑噩噩度过的(当时觉得和编程没多大关系),其他时间对算法接触也比较少,但是随着开发时间变长对一些底层代码/处理机制有所接触越发觉得算法的重要性,所以决定开始系统的学习(主要是刷力扣上的题目)和整理,也希望还没开始学习的人尽早开始。

系列文章收录《算法》专栏中。

力扣题目链接

问题描述

给你一个 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. 如果是0就直接返回0。
  2. 如果是负数需要判断是否为最小负数,如果是就直接返回0。(因为后面需要统一转成正数,Integer.MIN_VALUE取反加一后还是负数,正好反转也超过了限制所以直接返回0)
  3. 标记是正数还是负数,统一按照正数处理,转成字符串进行反转。
  4. 字符串反转之后,转成数字(反转后转数字可能溢出,直接捕获NumberFormatException异常返回0即可),数字根据第三步标记的正负数进行还原正负数。
package com.study.algorithm.math;

public class ReverseNum {
    public static int reverse(int x) {
        int result = 0;
        if (x == 0 || x == Integer.MIN_VALUE) {
            return result;
        }

        boolean isNegative = x < 0 ? true : false;
        StringBuilder stringBuilder;
        if (isNegative) {
            stringBuilder = new StringBuilder((~x + 1) + "");
        } else {
            stringBuilder = new StringBuilder(x + "");
        }
        Integer i;
        try {
            i = new Integer(stringBuilder.reverse().toString());
        } catch (NumberFormatException e) {
            return result;
        }

        result = isNegative ? ~i + 1 : i;
        return result;
    }

    public static void main(String[] args) {
        System.out.println((reverse(Integer.MIN_VALUE)));
    }
}

上面的代码是通过了,执行用时2ms,内存消耗39MB,效率不是很理想,时间消耗在于整数转字符串、字符串反转、字符串转数字。

数学

题解中的方式,使用到了%10得到最后一位,/10消除最后一位,这样就能实现反转。需要注意的是防止溢出,% /是不会产生的,防止溢出可以在产生的过程中检查是否小于Integer.MIN_VALUE / 10或者大于Integer.MAX_VALUE / 10。不要用乘法会导致检查过程中溢出。

时间复杂度为O(logx),空间为O(1)。

代码

public static int reverse(int x) {
    int result = 0;
    while (x != 0) {
        if (result > Integer.MAX_VALUE / 10 || result < Integer.MIN_VALUE / 10) {
            return 0;
        }
        int digit = x % 10;
        x = x / 10;
        result = result * 10 + digit;
    }
    return result;
}