Problem
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 :
输入 | 输出 |
---|---|
123 | 321 |
-123 | -321 |
120 | 21 |
注意 :
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为
[
−
2
31
,
2
31
−
1
]
[−2^{31}, 2^{31} − 1]
[−231,231−1]请根据这个假设,如果反转后整数溢出那么就返回 0。
Solving
首先考虑如何记录反转后的数,我们要从右至左依次获得输入数字(只考虑大于等于0的情况)的每一位数,可以依次用输入数字对10取余即可得到反转的每一位数(remainder),则当前轮得到的反转数 = 前一轮得到的反转数 * 10 + 当前轮得到的余数(remainder),依次迭代。
其次考虑溢出的问题,如果在得到最终的反转数后再进行是否溢出的判断则会出现得到的反转数可能已经溢出的情况,所以要在迭代进行到可能会溢出前进行判断,由于迭代只有进行到最后一轮时才会可能出现溢出的情况,前一轮不会出现溢出的情况,故我们可以通过前一轮得到反转数提前判断最后一轮是否会溢出,即有 最 后 一 轮 得 到 的 反 转 数 = 前 一 轮 得 到 的 反 转 数 ∗ 10 + r e m a i n d e r < 2 31 最后一轮得到的反转数 = 前一轮得到的反转数 * 10 + remainder < 2^{31} 最后一轮得到的反转数=前一轮得到的反转数∗10+remainder<231 前 一 轮 得 到 的 反 转 数 < ( 2 31 − r e m a i n d e r ) / 10 前一轮得到的反转数 < (2^{31} - remainder) / 10 前一轮得到的反转数<(231−remainder)/10以上公式的推导说明前一轮得到的反转数满足不等式的条件时,最终得到的反转数则不会出现溢出的情况。
最后考虑特殊情况,以上过程均建立在输入数为大于等于 0 的情况,当输入值小于 0 时,我们对输入值取其相反数即可;但是当输入值为 - 2^31 时,其相反数则超过可以储存的最大正整数,造成溢出,因此可以将其单独列出直接返回 0,从而避免溢出。
Code(C++)
class Solution {
public:
int reverse(int x) {
int y;
int digits = 0; //记录x的位数;
int remainder; //记录余数;
int revertedNumber = 0; //记录每一轮反转后的数;
if(x == -pow(2,31)){ //x为最小负整数时,-x会溢出,返回0;
return 0;
}
else if(x < 0){
y = -x;
}
else{
y = x;
}
while(y / pow(10,digits) >= 10){ //判断x的位数;
digits++;
}
for(int i=0; i <= digits-1; i++){
remainder = y % 10; //依次取出y的最后一位;
y = y / 10; //依次去掉y的最后一位;
revertedNumber = revertedNumber * 10 + remainder; //记录当前反转得到的数值;
}
if(x < 0 && revertedNumber < (pow(2,31) - y) / 10){ //判断是否溢出并加上对应的符号;
return -(revertedNumber *10 + y);
}
else if(x >= 0 && revertedNumber < (pow(2,31) - y) / 10){
return (revertedNumber *10 + y);
}
else{
return 0;
}
}
};
执行用时:0 ms
内存消耗:7.4 MB