002-整数反转 (Reverse Integer)
LeetCode 第7题 - 整数反转的详细题解
题目描述
给你一个 32 位的有符号整数 x,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位有符号整数的范围 [−2³¹, 2³¹ − 1],就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例
输入:x = 123
输出:321
输入:x = -123
输出:-321
输入:x = 120
输出:21
输入:x = 0
输出:0解题思路
通过数学运算逐位提取数字并重新组合,同时处理溢出情况。在每次乘以10之前检查是否会溢出,避免整数溢出问题。
JavaScript 解决方案
/**
* @param {number} x
* @return {number}
*/
const reverse = (x) => {
const INT_MAX = Math.pow(2, 31) - 1;
const INT_MIN = -Math.pow(2, 31);
let result = 0;
while (x !== 0) {
const digit = x % 10;
x = Math.trunc(x / 10);
// 检查溢出
if (result > INT_MAX / 10 ||
(result === Math.floor(INT_MAX / 10) && digit > 7)) {
return 0;
}
if (result < INT_MIN / 10 ||
(result === Math.ceil(INT_MIN / 10) && digit < -8)) {
return 0;
}
result = result * 10 + digit;
}
return result;
};复杂度分析
- 时间复杂度:O(log n),其中 n 是整数 x 的位数
- 空间复杂度:O(1),只使用了常数额外空间
测试用例
// 测试函数
const testReverse = () => {
const testCases = [
{ x: 123, expected: 321 },
{ x: -123, expected: -321 },
{ x: 120, expected: 21 },
{ x: 0, expected: 0 },
{ x: 1534236469, expected: 0 }, // 溢出情况
{ x: -2147483648, expected: 0 }, // 边界情况
{ x: 100, expected: 1 },
{ x: -100, expected: -1 },
{ x: 2147483647, expected: 0 }, // 最大整数
{ x: -2147483647, expected: 0 } // 最小整数
];
testCases.forEach((testCase, index) => {
const result = reverse(testCase.x);
const passed = result === testCase.expected;
console.log(`测试用例 ${index + 1}: ${passed ? '通过' : '失败'}`);
console.log(`输入: x = ${testCase.x}`);
console.log(`期望: ${testCase.expected}, 实际: ${result}\n`);
});
};
// 运行测试
testReverse();关键点总结
- 溢出检查:必须在每次乘以10之前检查是否会溢出
- 边界值处理:特别注意 INT_MAX (2147483647) 和 INT_MIN (-2147483648)
- 数学运算:使用
Math.trunc()处理负数除法 - 符号处理:负数反转后仍为负数
- 前导零:反转后前导零会自动消失
总结
这道题考察了以下重点:
- 整数溢出处理:这是面试中的常见考点
- 数学运算技巧:如何逐位提取和重组数字
- 边界条件:对极端情况的处理能力
- 算法优化:从字符串方法到数学方法的优化
数学方法是最优解,时间复杂度为 O(log n),空间复杂度为 O(1)。在实际面试中,建议先提出字符串解法,然后优化到数学解法,展示对性能的考虑。