【力扣】整数反转,判断是否溢出的数学解法

整数反转原题地址

方法一:数学

反转整数

如何反转一个整数呢?考虑整数操作的3个技巧:

  1. xmod10可以取出x的最低位,如x=123,xmod10=3。
  2. x/=10可以去掉x的最低位,如x=123,x/=10,x=12。
  3. x=x*10+y可以在x后面续上y,其中y是一位数,如x=123,y=4,x=x*10+y,x=1234。

假设要反转的整数为x,反转后的整数存储在变量rev中,rev一开始初始化为0,那么反复执行以下操作:

  1. digit=xmod10,取出x的最低位数。
  2. x/=10,去掉x的最低位数。
  3. rev=rev*10+digit,在rev后面续上digit。

直到x为0为止,此时rev存储的数据符合题目要求。

判断溢出

问题在于,如何判断插入后的数据是否超出[INT_MIN,INT_MAX]的范围,导致溢出?

我们来探索不等式INT\_MIN\leqslant n\leqslant INT\_MAX成立的充分必要条件。

先看右半边,即n\leqslant INT\_MAX

对于任意整数i,我们有i=\left \lfloor \frac{i}{10} \right \rfloor\times 10+i mod 10,如对于123,123/10=12,123mod10=3,123=12*10+3。

不等式化为:\left \lfloor \frac{n}{10} \right \rfloor\times 10+n mod 10=\left \lfloor \frac{INT\_MAX}{10} \right \rfloor\times 10+INT\_MAX mod 10,带入INT\_MAXmod10=7\left \lfloor \frac{n}{10} \right \rfloor=revnmod10=digit0\leqslant digit\leqslant 9

移项化简得:(rev-\left \lfloor \frac{INT\_MAX}{10} \right \rfloor)\times 10\leqslant 7-digit,记\left \lfloor \frac{INT\_MAX}{10} \right \rfloor=m

  1. 当rev=m时,如果还要推入数字,那么digit≤2,因为INT_MAX的最高位为2,此时不等式左边等于0,右边为正数,不等式恒成立。
  2. 当rev>m时,不等式左边至少是10,右边至多是7,不等式恒不成立。
  3. 当rev

所以原不等式右半边成立的充分必要条件是rev\leqslant m,即rev\leqslant\left \lfloor \frac{INT\_MAX}{10} \right \rfloor。同理左半边成立的充分必要条件是rev\geqslant \left \lceil \frac{INT\_MIN}{10} \right \rceil

原不等式成立的充分必要条件是\left \lceil \frac{INT\_MIN}{10} \right \rceil\leqslant rev\leqslant\left \lfloor \frac{INT\_MAX}{10} \right \rfloor

// 方法一:数学
class Solution {
public:
    int reverse(int x) {
        int rev = 0;
        while (x)
        {
            if (rev < INT_MIN / 10 || rev > INT_MAX / 10)
            {
                return 0;
            }

            // rev后面续上x的最低位
            rev = rev * 10 + x % 10;
            // 去掉x的最低位
            x /= 10;
        }

        return rev;
    }
};

你可能感兴趣的:(leetcode,算法,职场和发展)