题目名称:Reverse Integer

题目难度:Easy

题目描述:Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
Note:
The input is assumed to be a 32-bit signed integer. Your function should return 0 when the reversed integer overflows.

题目分析:
本题相对于上一道题目来讲难度高了点。
首先反转数字想到的便是先将数字的每一位分别取出来,然后按照相反的顺序组合起来。
这一步并不难,分别取出数字的位值可以用取模法:先将数字对10取模,便得到了最低位的数字,然后再将数字除以10,这样下次再对10取模就能得到倒数第二位的数字……如此重复下去,直到取出所有位的数字。将这些数字存储起来。之后再通过相反的顺序取出并组合成新的值便可初步得到结果。
本题的难点在于题目中的提示,提示说因为使用的是32位有符号数的表示法,所以反转过来的数字可能会超过32位的表示范围,答题者需要考虑到这一点。
首先,32位有符号数的范围是 -2147483648 到 2147483647。那末,如何判断一个有符号数的反转数是否超过了这个范围呢?
博主第一个想到的方法是直接简单粗暴的写一个判断,判断结果是否超出了上述范围:

if (result > 2147483647 || result < (-2147483648)) {
  return 0;
}

然而这种想法太天真,很明显是行不通的。因为result本身也是一个由32位表示的有符号数,他肯定是不会超过这个范围的。
举一个超过范围的例子:

Input: 1534236469
Output: 1056389759
Expected: 0

那么还有什么比较巧妙的方法吗?博主通过观察注意到,反转值超过范围的测试数他们基本都有一个特点,那就是反转值的每一位基本都与我们预期得到的数字不同。因为反转值已经超出了范围,所以系统自动将它范围化了,这种处理会导致在很多位上的数字跟我们预期的不一样,而且一样的可能性只有10%。我们可以利用这一点,写出新的检测:将结果的某一位跟与之对应的期望数相比较,如果不一样,则有90%的把握确定它超过了表示范围。如果想提高这个正确比例,只需增加比较的位数即可。
所以最后AC的代码如下:

class Solution {
public:
    int reverse(int x) {
        queue<int> q;
        int tx = x;
        while (tx != 0) {
          int temp = tx % 10;
          q.push(temp);
          tx /= 10;
        }
        int result = 0;
        int store;
        while (!q.empty()) {
          result = result*10 + q.front();
          store = q.front();
          q.pop();
        }
        if (store != result%10)
          return 0;
        return result;
    }
};
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐