来源:力扣(LeetCode)
链接:力扣
题目描述:
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [,
],就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
一个最简单的想法,就是把给定的整数 x先进行反转,再检查是否仍在 32 位有符号整数范围内。32 位有符号整数的范围是 [-2147483648, 2147483647] ,如果一个数的位数小于 10 ,可以断定它反转后仍然处于 32 位有符号整数之内;如果它的位数等于 10,则与两端点值进行比较即可。
int reverse(int x){
if(x<10&&x>-10)return x;
if(x==2147483647||x==-2147483648)return 0;
int f=1,xx=x,t=0,ans=0,flag=0;
if(x<0)f=-1,xx*=f;
int maxnp[]={2,1,4,7,4,8,3,6,4,7};
int maxnn[]={2,1,4,7,4,8,3,6,4,8};
int numx[12];
while(xx>0)
{
if(xx%10==0)//要注意原数x的末尾0在反转后会变成前导0,需要去掉
{
if(flag==1)numx[t++]=xx%10;
xx/=10;
}
else flag=1,numx[t++]=xx%10,xx/=10;
}
if(t<10)//不足10位可直接反转输出
for(int i=0;i<t;++i)
ans=ans*10+numx[i];
else
{
for(int i=0;i<t;++i)
{
if(f==1)//正数
{
if(numx[i]>maxnp[i])//按位比较
{
flag=0;break;
}
else if(numx[i]<maxnp[i])
break;
}
else//负数
{
if(numx[i]>maxnn[i])
{
flag=0;break;
}
else if(numx[i]<maxnn[i])
break;
}
}
if(!flag)return ans;
else
{
for(int i=0;i<t;++i)
ans=ans*10+numx[i];
}
}
return ans*f;
}
从上面的方法可以看出,其实只有在一个数的位数为 10 的时候,才需要考虑反转后是否存在溢出的情况。而直接判断一个 10 位数反转后是否溢出有些困难,可以将这个问题转化为考虑这个数的 9 位是否比 INT_MAX/10 大或者比 INT_MIN/10 小。
这里不需要考虑最后一位,是因为如果一个数处在 32 位整数范围内,它的第一位必然要小于等于 2,反转后的数的最后一位必然也小于 2。如果这个数在 9 位的条件下满足比 INT_MAX/10 小或者比 INT_MIN/10 大,则说明这个数在反转 9 位的情况下是满足条件的,那么不上最后一位,仍满足条件。
int reverse(int x){
int ans=0;
while(x!=0)
{
if(ans<INT_MIN/10||ans>INT_MAX/10)return 0;
ans=ans*10+x%10,x/=10;
}
return ans;
}