整数反转
Leetcode题目:(链接:https://leetcode-cn.com/problems/reverse-integer)
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
示例 :
输入: 123
输出: 321
输入: -123
输出: -321
输入: 120
输出: 21
第一反应是转成字符串,反转后再转回来,确实也可行,但是时间和空间上实在是不咋滴,不知道这个想法是不是没救了。
题解:不需要转换字符转,j输入与输出看作两个栈的话,我们需要做的工作就是将输入的尾部数字弹出,再放入输出栈。这个过程要在没有栈或数组的情况下以借助数学办法模拟出入栈。
//pop operation ---输入出栈
x = x % 10;
x = x / 10;
//push operation ---输出入栈
temp = res * 10 + pop;
res = temp;
这里的问题是temp = res * 10 + pop这一步可能发生溢出的情况,因此我们需要在之前检查这个语句是否会溢出。
先假设res为正的情况:
1.若temp = res * 10 + pop会导致溢出,则res
≥
\ge
≥
I
N
T
M
A
X
10
\frac{INTMAX}{10}
10INTMAX。
2.若res >
I
N
T
M
A
X
10
\frac{INTMAX}{10}
10INTMAX,则temp = res * 10 + pop一定溢出。
1.若res = w
I
N
T
M
A
X
10
\frac{INTMAX}{10}
10INTMAX,则pop > 71时,temp = res * 10 + pop一定溢出。
当res为负时同理。
代码如下
//Java
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x = x / 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
时间复杂度:
O
(
l
o
g
(
x
)
)
O(log(x))
O(log(x)),
x
x
x中约有
l
o
g
10
(
x
)
log_{10}(x)
log10(x)位数字。
空间复杂度:
O
(
1
)
O(1)
O(1)。
通过计算231的末位数,我们可以得知末位为8,故231 - 1末位为7。虽然int型最大数首位为2,也就是说如果进行最大次数循环时,末位不可能大于7,但是当自己不知道int具体范围时,此办法为通解。 ↩︎