leetcode算法题7——整数反转

整数反转(难度:简单)

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

示例 1:
输入: 123
输出: 321
 示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21

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

答:求一个数的倒数,如果不考虑溢出问题的话是很简单的,只需要不断地除以十取余数,然后除以 10 去掉个位数,然后用一个变量保存倒置的数就行了,代码如下:

class Solution {
public:
    int rev = 0;
    while (x != 0) {
        int pop;
        pop = x % 10;
        x /= 10;
        rev = rev * 10 + pop;
    }
    return rev;
}
};

但是提交后很明显会报错,因为我们并没有考虑溢出问题,比如:
leetcode算法题7——整数反转_第1张图片
为什么呢?倒置过来不应该是 9646324351 吗?其实题目里讲了,int 的范围是 [ − 2 31 , 2 31 − 1 ] [-2^{31} ,2^{31}-1] [231,2311]也就是 [ − 2147483648 , 2147483647 ] [-2147483648,2147483647] [2147483648,2147483647] 。明显 9646324351 9646324351 9646324351 超出了范围,造成了溢出。所以我们需要在输出前,判断是否溢出。
方法一:
我们对 temp= rev * 10 + pop; 进行讨论。intMAX = 2147483647 , intMin = - 2147483648 。
对于大于 intMax 的讨论,此时 x 一定是正数,pop 也是正数。
1.如果 rev > intMax / 10 ,那么没的说,此时肯定溢出了。
2.如果 rev == intMax / 10 = 2147483647 / 10 = 214748364 ,此时 rev * 10 就是 2147483640 如果 pop 大于 7 ,那么就一定溢出了。但是!如果假设 pop 等于 8,那么意味着原数 x 是 8463847412 了,输入的是 int ,而此时是溢出的状态,所以不可能输入,所以意味着 pop 不可能大于 7 ,也就意味着 rev == intMax / 10 时不会造成溢出。
3.如果 rev < intMax / 10 ,意味着 rev 最大是 214748363 , rev * 10 就是 2147483630 , 此时再加上 pop ,一定不会溢出。
也就是说,输入的x也是一个整型数,所以x的范围也应该在 -2147483648~2147483647 之间,那么x的第一位只能是1或者2,翻转之后 rev 的最后一位只能是1或2,所以 rev 只能是 2147483641 或 2147483642 都在 int 的范围内。但是它们对应的x为 1463847412 和 2463847412,后者超出了数值范围。所以当过程中 rev 等于 214748364 时, 输入的x只能为 1463847412, 翻转后的结果为 2147483641,都在正确的范围内。
代码如下:

class Solution {
public:
    int reverse(int x) {
        int res = 0;
        while (x != 0) {
            if (abs(res) > INT_MAX / 10) return 0;
            res = res * 10 + x % 10;
            x /= 10;
        }
        return res;
    }
};

方法二:用 long 型变量保存计算结果

class Solution {
public:
    int reverse(int x) {
        long res = 0;
        while (x != 0) {
            res = 10 * res + x % 10;
            x /= 10;
        }
        return (res > INT_MAX || res < INT_MIN) ? 0 : res;
    }
};

用 long 型数据,其数值范围为 -9223372036854775808~9223372036854775807, 远大于 int 型这样就不会出现溢出问题,最后返回的时候判断是否在 int 返回内即可。

附C++ int 型负数除法与求模运算

1、除法运算:向零取整(向0方向取最接近精确值的整数,类比向上取整和向下取整)

比如:10/(-4) = -2;10/4 = 2;

2、求模运算: (1) |小| % |大| = |小| ,符号同前; (2) |大 | % |小| = |余| ,符号同前 (|n|指n的绝对值,求模时参照该公式:“余数=被除数-商*除数)

比如:

     3%4 = 3(-3)%(-4) = -3  
  (-3)%4 = -33%(-4) = 35%3 = 2(-5)%(-3) = -2(-5)%3 = -25%(-3) = 2

你可能感兴趣的:(LeetCode)