题目
给出一个32位的有符号整数,你需要将这个整数中每位上的数字进行反转。
注意:假设我们的环境只能存储得下32位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回0。
示例1:
输入: 123
输出: 321
示例2:
输入: -123
输出: -321
示例3:
输入: 120
输出: 21
思路
反转整数的方法可以与反转字符串进行类比(循环将字符串最后一位压入栈,最后循环弹出即可)。对于反转整数,用栈虽然可以实现,但对于此题,使用数学方法进行压入与弹出更好,因为使用数学方法可以减小算法的复杂度。
- 压入:
int pop = x % 10;
x /= 10;
- 弹出:
int rev = rev * 10 + pop;
但是上面rev会存在溢出的情况,即超出int的表示范围。最好的解决方法是:在每次计算新值rev时都判断是否溢出。
溢出条件有两个,一个是大于整数最大值MAX_VALUE,另一个是小于整数最小值MIN_VALUE,设当前计算结果为rev,下一位为pop。
- 从
rev * 10 + pop > MAX_VALUE
这个溢出条件来看:- 当出现
rev > MAX_VALUE / 10
且 还有pop需要添加时,则一定溢出。 - 当出现
rev == MAX_VALUE / 10
且 pop > 7 时,则一定溢出,7是2^31 - 1的个位数。
- 当出现
- 从
rev * 10 + pop < MIN_VALUE
这个溢出条件来看:- 当出现
rev < MIN_VALUE / 10
且 还有pop需要添加 时,则一定溢出。 - 当出现
rev == MIN_VALUE / 10
且 pop < -8 时,则一定溢出,8是-2^31的个位数。
- 当出现
解答
class Solution {
public:
int reverse(int x) {
//如果使用long来保存rev,就可以直接比较rev与int的上下界值
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
//上界
if (rev > INT_MAX/10 ||
(rev == INT_MAX/10 && pop > 7))
return 0;
//下界
if (rev < INT_MIN/10 ||
(rev == INT_MIN/10 && pop < -8))
return 0;
rev = rev * 10 + pop;
}
return rev;
}
};
【关注公众号DoCode,每日一道LeetCode,将零碎时间利用起来】