今天的这道题还是属于有点小趣味的,对于经验丰富的码农们简直就是一眼就能观之一二。但对于我这个小白来说确实是一个积累经验的一个小小的台阶。
本篇内容是关于Leetcode新手村字符串的整数反转题目:整数反转。
一、题目:(题目来源Leetcode)
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。假设环境不允许存储 64 位整数(有符号或无符号)。
![]()
二、分析:
刚读到这道题的时候感觉,这道题看起来还是很基础的吗,虽然不能像字符串一样对于数组对之间相互交换,但按照数字位提取的方法还是有解决的逻辑的。
既然x本身就只是个数值,那么不存在像之前数组有空间分配需要原地处理的格外要求了。那么就是直接数值运算的方向去思考。如果额外 int y,使x尾部提取出来的数都推入y中即可。提取x尾数可以利用%10取余数的方式。同时x除以10,y在原来基础上乘以10再加上这个余数即可以实现这个操作。在对于最后取值的出的数值范围进行判定,满足输出,不满足输出0.
此时书写的代码如下:
class Solution { public: int reverse(int x) { int y = 0; //倒叙数值暂存 int temp = 0; //尾数暂存 //对于x进行反转 //提取结尾数 while( x != 0){ temp = x % 10; y = y * 10 + temp; x = x / 10; } x = y; //直接输出y也可以,不够规范 return x; } };
三、发现问题:
但这时候问题就出现了:
1、需不需要额外对于附属情况分析。2、若y*10的时候溢出整型范围该如何在语句执行前限制。
四、试验并解决问题:
首先对于第一个问题:在最初时候确实用了一个格外变量来判定正负这件事。但是最后得出的结果负数反而得不出来负数。从结果方面可以看出来在对于取余数的时候已经进行了正常数值正负的运算,不需要额外判定。(如:-123 % 10 的结果为 -3)
对于第二个问题溢出的方面,则需要考虑特殊情况。因为整型限制在了[-2^31,2^31-1]的范围之间。
虽然系统限制住了输入的x不会溢出的现象,但是我们额外引入的y所赋值的却不能保证运算过程会不会溢出。
举个例子:214 748 364是int的上限。但是我们输入的是173 847 412,当我们y提取到第六位(214 748 37)时再y*10则就会溢出。因此需要在执行前进行如下条件限制:
if ( y > INT_MAX/10 || ( y == INT_MAX/10 && temp > INT_MAX % 10)) return 0; if ( y < INT_MIN/10 || ( y == INT_MIN/10 && temp > INT_MAX % 10)) return 0;
五、自己提交的代码:
(其中,自己写的过程中的痕迹用注释的形式表现出来)
class Solution {
public:
int reverse(int x) {
int y = 0; //倒叙数值暂存
int temp = 0; //尾数暂存
//int sym; 判断正负
//对于x进行反转
/* if( x < 0 )
sym = 1; */
//提取结尾数
while( x != 0){
temp = x % 10;
//官方所提供的处理溢出的方式:
if ( y > INT_MAX/10 || ( y == INT_MAX/10 && temp > INT_MAX % 10))
return 0;
if ( y < INT_MIN/10 || ( y == INT_MIN/10 && temp > INT_MAX % 10))
return 0;
y = y * 10 + temp; //可能出现反转后y*10溢出情况
x = x / 10;
/* 自己写的处理溢出的错误方式:
if( y >= -214748365 && y <= 214748364 ){
if((y=-214748364 && temp > 7)||(y=214748364 && temp >= 7)) return 0;
y = y * 10 + temp; //可能出现反转后y*10溢出情况
x = x / 10;
}
else return 0; */
}
x = y;
/* if( sym == 1 )
x = -y;
else x = y; */
return x;
}
};
六、学习小汇:
int类型上下限:INT_MAX,INT_MIN
数字个位数提取:x % 10;(其中x为负数取的余数也是负数)