整数反转
题目描述
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例
输入:x = -123
输出:-321
输入:x = 120
输出:21
C++解题代码
class Solution {
public:
int reverse(int x) {
int Sign = (x < 0 ? -1: 1);
int y = abs(x);
int length = 0;
int rem;
int newx=0;
int num=0;
while(y>0)
{
y=y/10;
length++;
}
y=abs(x);
while(y>=1)
{
rem=y%10;
y=y/10;
//Determine if there is overflow
if(num==0&&((rem*pow(10,(length-1)))>(pow(2,31))))
{
return 0;
}
if(num!=0&&(newx+rem*pow(10,(length-1)))/10>(pow(2,31)/10))
{
return 0;
}
newx+=rem*pow(10,(length-1));
length--;
num++;
}
newx=Sign*newx;
return ((-1*pow(2,31)<=newx)&&(newx<=(pow(2,31)-1))?newx:0);
}
};
题目解析
由题目描述与示例不难看出,想做出这道题需要解决以下几个问题:
- 按顺序取出x中的每位数字
- 利用取出的数字把x反转组成一个新的数字
- 判断这个新的数字是否在范围内并输出相应答案
- 题目假设不允许存储64位整数,所以要考虑在计算过程中溢出怎么办(我一开始也没考虑到这个)
代码解析
三目运算符
考虑到可能有负数,首先我把x的单独存了一下,后续都是对x的绝对值进行操作,最后再给反转后的数字加上符号即可,但其实直接对x进行操作也是可以的,这个我们后续再说,这里用到了一个三目运算符。三目运算符表达式如下:
Exp1 ? Exp2 : Exp3;
若Exp1对应的表达式为真,则返回Exp2表达式对应的值,反之则返回Exp3表达式对应的值。与if, else语句的作用类似。更多内容请参考下面的网址。
除此之外剩下的内容就比较简单了,不过我写的比较复杂,先是计算了一下x有几位数字,后续反转时会用到,为了按顺序取出x中的数字,我在循环里每次将x的值除10取余,这样就能按顺序从低位到高位取出x中的每位数字。反转时则根据刚刚得出的x的位数把取出的数字乘以相应的10的幂次再求和即可。最后再把x的符号与反转后的数字相乘,最后判断是否满足范围要求再输出即可。
防止溢出
刚开始一直没想出来,参考的官方结题思路,其实只要在赋值给int类型之前把原来那个值除10跟最大值比即可,因为我写的代码比较奇怪?所以还需要额外判断一下初始的情况。至于负号的情况,我想了一下应该不需要额外判断。
运行结果
学习与反思
看了评论里大家的代码后,感觉自己写的太冗长了,参考评论区一位大神的代码,截图如下:
我的思路跟这位大神基本一致,也用到了取余然后x每次除10的方法,但人家的代码明显更简洁,不需要计算x的位数,可以直接将题目解析中的第一步和第二步结合起来。虽然这位大神也没考虑溢出的情况,但人家的思路也非常值得我学习。