0007.整数反转
难度:🟡 中等
标签:数学
链接:7. 整数反转
题目描述
给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
解题思路
核心思想
本题的核心思想是通过数学运算来逐位“弹出”原数字的末位并“推入”到结果数字的末位,从而实现数字的反转。在此过程中,关键的难点在于处理符号以及判断反转后的结果是否会超出 32 位有符号整数的范围。
思路选择
数学运算法 是解决此问题的标准思路。我们不将数字转换为字符串,而是直接通过循环、取模 (%
) 和除法 (/
) 来操作数字。
关键步骤
处理符号:首先判断输入数字
x
的正负,并将此信息存储起来。后续的操作都基于x
的绝对值进行。初始化:初始化结果
result = 0
。循环反转:当
x
不为 0 时,持续循环。 a. 取末位:通过x % 10
获取x
的最后一个数字。 b. 构建新数:将result
乘以 10 并加上刚取出的末位数字,result = result * 10 + (x % 10)
。 c. 移除末位:通过Math.floor(x / 10)
将x
的最后一位移除。恢复符号:循环结束后,根据第一步中记录的符号信息,给
result
加上正确的符号。检查溢出:将最终的
result
与 32 位有符号整数的范围[−2^31, 2^31 − 1]
进行比较。如果超出范围,返回 0;否则,返回result
。
代码实现
/**
* @param {number} x
* @return {number}
*/
var reverse = function (x) {
const isNegative = x < 0;
let result = 0;
// 使用绝对值进行反转操作
x = Math.abs(x);
while (x !== 0) {
// 取出 x 的末位,并追加到 result 的末尾
result = result * 10 + (x % 10);
// 移除 x 的末位
x = Math.floor(x / 10);
}
// 恢复符号
if (isNegative) {
result = -1 * result;
}
// 检查结果是否在32位有符号整数范围内
if (result < Math.pow(-2, 31) || result > Math.pow(2, 31) - 1) {
return 0;
}
return result;
};
复杂度分析
时间复杂度:O(log x) 其中 x 是输入整数。循环的次数取决于 x 的十进制位数,而位数与 log₁₀(x) 成正比。
空间复杂度:O(1) 我们只使用了常数个额外变量,空间消耗是恒定的。
相关题目
总结
本题是一道经典的数学与位运算面试题,它不仅考察了基本的数字操作能力,更重要的是考察了对整数溢出这一边界情况的处理。在处理整数问题时,时刻注意其表示范围是写出健壮代码的关键。