7.Reverse Integer - Easy
Description
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
Note:
The input is assumed to be a 32-bit signed integer. Your function should return 0 when the reversed integer overflows.
解题经过
思路
首先想到的是int转string,逆序,再string转int,还要在string的基础上判断溢出,想想就觉得很麻烦。所以很快就换了种思路,对int取模运算拿到每一位,再对结果不断乘10再相加。觉得这个很容易,于是就动手写了。
int reverse(int x) {
while(x) {
int last_num = x % 10;
x = (x - last_num) / 10;
result = result * 10 + last_num;
}
if(result > INT_MAX || result < INT_MIN) return 0;
return result;
}
困难
提交之后发现溢出情况下总是WA,中间算的步骤没有问题,一定是溢出没有处理好。
上面的INT_MAX来自climits头文件的定义,我还换用了numeric_limits模板的方法和自己宏定义最值的方法,以为问题出在这两个值上,但都没产生积极作用,甚至模板的方法WA的样例还不止溢出的情况。
原来问题所在并不是那两个值,而是经过了上面计算的步骤,即使有溢出,result也会是一个实际上错误的正常int值。就不应该拿一个整形的result跟INT_MAX作比较。
最终提交
我只能想到用一大堆条件语句在result要溢出前进行判断的处理方法,然而这种做法愚蠢而低效。所以我放弃了抵抗,向另一种蠢得不那么厉害的方法低头——就是开头说到的转string的方法。AC代码如下:
#include <string>
#include <sstream>
#include <cstdlib>
class Solution {
public:
int reverse(int x) {
stringstream ss;
ss << x;
string str_x;
ss >> str_x;
string ret = reverse_checkStr(str_x);
if(ret == "OverFlow") return 0;
else return atoi(ret.c_str());
}
string reverse_checkStr(string s) {
int end = s.length() - 1; //the last index
if(s[0] == '-') { //处理下标真的是件很烦的事
for(int i = 1; i <= end / 2; ++i) {
int temp = s[i];
s[i] = s[end - i + 1];
s[end - i + 1] = temp;
}
if(end == 10) {
if(s.substr(1, 10) > "2147483648") return "OverFlow";
}
}
else {
for(int i = 0; i <= (end - 1) / 2; ++i) {
int temp = s[i];
s[i] = s[end - i];
s[end - i] = temp;
}
if(end == 9) {
if(s > "2147483647") return "OverFlow";
}
}
return s;
}
};
总结学习
交完看了别人的解法,溢出问题有两个很聪明的对策。
- 在计算的过程中先用一个长整形暂存结果,然后再拿它跟int的最值比较;
- 算完之后再检查,该保持不变的地方是不是发生了变化,有变就有溢出。