剑指leetcode—整数反转

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

对int类型的简单介绍
int为4个字节:1字节=8位,所以int为32位在计算机中存储的二进制位数。

int -2147483648~2147483647

unsigned int 0~4294967295

示例 1:

输入: 123
输出: 321

示例 2:

输入: -123
输出: -321

示例 3:

输入: 120
输出: 21

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

算法分析:
这题算法很简单,最关键的点是注意事项,如果反转后整数溢出就直接返回0;
这里的溢出是指实时的,只要一溢出就会立刻出错,所以在每一次计算sum的之前都要判断一次会不会溢出。
C语言实现:

int reverse(int x){
    int sum=0;
    int temp=0;
    while(x)
    {
        temp=x%10;
          x=x/10;
       if ( sum > 2147483647/10 || (sum == 2147483647 / 10 &&temp> 7)) return 0;
        if (sum < -2147483648/10 || (sum == -2147483648/ 10 && temp < -8)) return 0;
         sum=sum*10+temp;
    }
    return sum;
}

计算sum的值必须在两个if语句之前

分析:
sum=sum*10+temp这一语句很容易导致溢出发生,幸运的是,事先检查这个语句是否会导致溢出很容易。
为了便于解释,我们假设 sum是正数。

  1. 如果
  2. sum= sum⋅10+pop导致溢出,那么一定有后面的sum≥INTMAX/10。
  3. 如果 后面的sum>INTMAX/10​,那么 sum= sum⋅10+pop一定会溢出。
  4. 如果 后面的sum==INTMAX/10​,那么只要 temp>7, sum= sum⋅10+temp就会溢出。

java语言实现

class Solution {
    public int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
}

还可以对此算法进行改进:

  • 最大的值与最小的值为:[−2^31, 2^31 − 1], 即:[-2147483648, 2147483647]。
  • 如果 y * 10 + x % 10溢出,则 y>=214748364 。
  • 当y=214748364时,输入的值只能是1463847412,不溢出。

因为在int所可以表示的最大值和最小值中的首数字只能是2或者1。

即:y > 214748364 || y < -214748364 必定溢出
代码如下:

class Solution {
    public int reverse(int x) {
        int y = 0;
        while (x != 0) {
            if (y > 214748364 || y < -214748364) {
                return 0;
            }
            y = y * 10 + x % 10;
            x = x / 10;
        }
        return y;
    }
}

你可能感兴趣的:(leetcode刷题之路)