今天完成的是第七题,也是目前做过的最简单的题,原题如下:
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!
If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100.
Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?
For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
对于整数的操作向来要比字符串的操作简单。该题思路很清晰,只需要得到整数各位的数字,再逆序输出即可。由于int类型在C++中已经定义(-2147483648~2147483647),对于整数各位数字遍历算法的复杂度均为常数阶(尽量直接对整数进行操作,不要把问题复杂化,我一开始竟然想转成字符数组再倒置。。。),因此重难点不在考察优化时间复杂度,而在各种特殊情况和整数越界如何处理上(本题也已给出提示,大大降低了难度)。
首先,根据提示1,我们需要对原整数进行讨论,分为末位为0和不为0两种情况,对为0的需要先去除末位的0(整数0需要单独考虑);
其次,考虑到负数在取余取整上比正数的结果多了个负号(会导致后面的还原操作出现问题),先将正负数统一,操作包括统一范围(对-2147483648单独考虑)和统一符号(取绝对值);
然后,将整数各位数字倒序输出;
最后,根据提示2,我们需要对倒置后的整数进行是否越界的判断,判断过程很简单,只需比较倒置的数和临界值的大小即可,越界的数直接返回0,不越界的返回倒置后的数。
代码如下:
#include "stdafx.h"
#include <iostream>
#include <limits.h>//定义INT_MAX和INT_MIN
#include <math.h>
#include <vector>
using namespace std;
int reverse(int x) {
if(x==0)return 0;
if(x==INT_MIN)return 0;//使得正负整数范围对称
int num = x;
//对于末位为0的数,清除末位的0
while(num % 10==0)num = num/10;
<span style="white-space:pre"> </span>vector<int> rc;
if(x<0)num=abs(num);
while(num != 0){rc.push_back(num%10);num = num/10;}
//判断逆向整数是否越界
if(rc.size()==10){
vector<int> c;
int max = INT_MAX;
while(max != 0){c.push_back(max%10);max = max/10;}
for(int i = 0;i<10;i++){
if(rc[i]==c[9-i])continue;
else if(rc[i]<c[9-i])break;
else return 0;
}
}
//重构
int rx = 0;
for(int i = 0;i<rc.size();i++)
rx = rc[i] + rx*10;
if(x<0)return -rx;
else return rx;
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 2147483647;
int rx = reverse(x);
cout<<"the reverse of "<<x<<" is: "<<rx<<endl;
return 0;
}
总结:
1.考虑问题一定要全面细致,如果本题不给出提示,也要像上述一样讨论分析;
2.牢记和数字有关的常用变量类型的取值范围;