题目
给你一个 32 位的有符号整数 x ,返回 x 中每位上的数字反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [-231,231-1],就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
解答1:long定义直接防止溢出
思路
%10是取最后一位,/10是抹去最后一位,理解之后自然非常简单。
需要的头文件
limits.h
代码
/*
* @lc app=leetcode.cn id=7 lang=cpp
*
* [7] 整数反转
*/
// @lc code=start
#include <limits.h>
using namespace std;
class Solution
{
public:
int reverse(int x)
{
// 注意这里为什么要定义long而不是int
long rex = 0;
while (x)
{
// rex增大10倍后面就会多出一个0,这个0的位置就是留给x%10的值
// x%10就是取x最后一位数
rex = rex * 10 + x % 10;
//x/10就是把最后一位数抹掉
x /= 10;
}
// 超过最大值或小于最小值,则返回0
// 否则符合规则,直接返回本身
return rex > INT_MAX || rex < INT_MIN ? 0 : rex;
}
};
// @lc code=end
时间复杂度和空间复杂度
- 时间复杂度:数字 X 的位数,可以用log10X表示。所以为 ***O(log10X)***。
- 空间复杂度: O(1) 。
解答2:int解法如何防止溢出
思路
%10是取最后一位,/10是抹去最后一位,理解之后自然非常简单。
在解法1中,如果把long换成int,rex = rex * 10 + x % 10;
这一表达式就有溢出的危险。
所以分析溢出情况如下:
- 整型上下限分别是
2147483647
和-2147483648
; - 溢出只取决于最后一位数。那么无论如何,当溢出时,rex一定大于等于2147483640,即rex ≥ \geq ≥INT_MAX/10;
- 当rex>INT_MAX/10时,一定溢出,因为这时候rex一定比21474836 5 0还要大(注意重点)。
- 当rex=INT_MAX/10时,如果x%10>7,那么就溢出了(参考刚刚说过的整型上下限)。
- 负数用同样的道理解决。
需要的头文件
limits.h
代码
/*
* @lc app=leetcode.cn id=7 lang=cpp
*
* [7] 整数反转
*/
// @lc code=start
#include <limits.h>
using namespace std;
class Solution
{
public:
int reverse(int x)
{
// 注意这里为什么要定义long而不是int
long rex = 0;
while (x)
{
//先做检查,超过最大值或小于最小值,则返回0
if (rex > INT_MAX / 10 || (rex == INT_MAX / 10 && x % 10 > 7))
{
return 0;
}
if (rex < INT_MIN / 10 || (rex == INT_MIN / 10 && x % 10 < -8))
return 0;
// rex增大10倍后面就会多出一个0,这个0的位置就是留给x%10的值
// x%10就是取x最后一位数
rex = rex * 10 + x % 10;
//x/10就是把最后一位数抹掉
x /= 10;
}
// while中无错误,符合规则,直接返回本身
return rex > INT_MAX || rex < INT_MIN ? 0 : rex;
}
};
// @lc code=end
时间复杂度和空间复杂度
- 时间复杂度:数字 X 的位数,可以用log10X表示。所以为 ***O(log10X)***。
- 空间复杂度: O(1) 。
反思与总结
- 记住/和%的作用,发散思维。
- 注意数字型运算时发生的溢出现象。