题目来源: 7. 整数反转
题目描述:
- 描述: 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号)。
- 示例:
示例1:
输入:x = 123
输出:321
示例2:
输入:x = -123
输出:-321
思路
思路1 记rev 为翻转后的数字,为完成翻转,我们可以重复「弹出」x 的末尾数字,将其「推入」rev 的末尾,直至 x 为0 要在没有辅助栈或数组的帮助下「弹出」和「推入」数字,我们可以使用如下数学方法:
// 弹出 x 的末尾数字 digit
digit = x % 10
x /= 10
// 将数字 digit 推入 rev 末尾
rev = rev * 10 + digit
题目需要判断反转后的数字是否超过32 位有符号整数的范围,例如x=2123456789 反转后的rev=9876543212>=2147483647,超过了32 位有符号整数的范围。
因此我们需要在「推入」数字之前,判断是否满足≤rev⋅10+digit≤
若该不等式不成立则返回0。
但是题目要求不允许使用64 位整数,即运算过程中的数字必须在32 位有符号整数的范围内,因此我们不能直接按照上述式子计算,需要另寻他路。
考虑x>0 的情况,记INT_MAX==2147483647,由于 INT_MAX=⌊INT_MAX/10⌋⋅10+(INT_MAXmod10)=⌊INT_MAX/10⌋⋅10+7
则不等式rev⋅10+digit≤INT_MAX
等价于rev⋅10+digit≤⌊INT_MAX/10⌋⋅10+7
移项得(rev−⌊INT_MAX/10⌋⋅10≤7−digit
讨论该不等式成立的条件:
若rev>⌊INT_MAX/10⌋,由于digit≥0,不等式不成立。 若rev=⌊INT_MAX/10⌋,当且仅当digit≤7 时,不等式成立。 若rev<⌊INT_MAX/10⌋,由于digit≤9,不等式成立。
注意到当rev=⌊INT_MAX/10⌋时若还能推入数字,则说明x 的位数与INT_MAX 的位数相同,且要推入的数字digit 为x 的最高位。由于x 不超过INT_MAX,因此digit 不会超过INT_MAX 的最高位,即digit≤2。所以实际上当rev=⌊INT_MAX/10⌋时不等式必定成立。
因此判定条件可简化为:当且仅当rev≤⌊INT_MAX/10⌋时,不等式成立。
综上所述,判断不等式≤rev⋅10+digit≤是否成立,可改为判断不等式⌈/10≤rev≤⌊/10⌋是否成立,若不成立则返回 0。
具体实现1
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
if (rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10) {
return 0;
}
int digit = x % 10;
x /= 10;
rev = rev * 10 + digit;
}
return rev;
}
}
复杂度分析1:
-
时间复杂度:O(log∣x∣)。翻转的次数即x 十进制的位数。
-
空间复杂度: