7. 整数反转
题目
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例
示例 1: 输入: 123 输出: 321
示例 2: 输入: -123 输出: -321
示例 3: 输入: 120 输出: 21
注意
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
我的方案
利用StringBuffer 做中间装换
Java源码
class Solution {
public int reverse(int x) {
if (x > -10 && x < 10) {
return x;
}
long subFlag = x < 0 ? -1l : 1l;
StringBuffer buffer = new StringBuffer().append(x * subFlag);
long y = Long.valueOf(buffer.reverse().toString()) * subFlag;
if (y > Integer.MAX_VALUE || y < Integer.MIN_VALUE)
return 0;
return (int) (y);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
Dart源码
final num MAX_VALUE = pow(2, 31) - 1;
final num MIN_VALUE = -pow(2, 31);
if (x > -10 && x < 10) {
return x;
}
num subFlag = x < 0 ? -1 : 1;
String str = (x * subFlag).toString();
int length = str.length;
StringBuffer buffer = new StringBuffer();
while (length > 0) {
buffer.write(str.substring(length - 1, length));
length--;
}
num y = num.parse(buffer.toString()) * subFlag;
if (y > MAX_VALUE || y < MIN_VALUE) return 0;
return y.toInt();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
推荐方案
我们可以一次构建反转整数的一位数字。在这样做的时候,我们可以预先检查向原整数附加另一位数字是否会导致溢出。
- 不考虑使用辅助变量类型的情况下,我们可以使用数学方法。
// 循环计算,直到全部推出为止
while
// 求个位数字:
pop = x % 10;
// 将个位推出
x /= 10;
// 计算转换后的数
rev = rev * 10 + pop;
2
3
4
5
6
7
8
- 关键一步在理解
temp = rev * 10 + pop;
的取值过程,我们不妨将他转换成一个不等式的解答。
题目
已知 MAX = 2147483647,MIN = -2147483648, f(rev,pop) = rev * 10 + pop, 且 rev 和 pop都为整数,且 -9 <= pop <= 9, 求 rev和pop在什么条件下 MIN <= f(rev,pop) <= MAX ;
解题
MIN <= f(rev,pop) <= MAX 等价于 !(f(rev,pop)>MAX || f(rev,pop)<MIN);
我们分析两个临界点即可
- 高于 MAX 的情况
rev * 10 + pop > MAX 时,对与rev来说,分以下3种情况:
1. rev < MAX / 10;∵ 是取整,所以 rev <= 214748363,而 pop <= 9, ∴ f(rev,pop)<=2147483639 < MAX,符合条件 。 2. rev = MAX / 10;∵ 是取整,所以 rev = 214748364, ∴ pop <=7 时 f(rev,pop) 符合条件,pop>7 时,不符合条件。 3. rev > MAX / 10;∵ 是取整,所以 rev >= 214748365,∴ f(rev,pop) 不符合条件
- 低于 MIN 的情况
rev * 10 + pop < MIN 时,对于rev来说,也分以下3中情况讨论:
1. rev < MIN / 10; ∵ 是取整,所以 rev <= -214748365,f(rev,pop) 不符合条件
2. rev = MIN / 10; ∵ 是取整,所以 rev = -214748364, ∴ pop >= -8 时 f(rev,pop) 符合条件,pop < -8 时,不符合条件
3. rev > MIN / 10; ∵ 是取整,所以 rev >= -214748363,而 pop >= -9, ∴ f(rev,pop)>= -2147483639 > MIN,符合条件 。
总结 当 (rev < MAX / 10 && rev > MIN / 10) || (rev = MAX / 10 && pop < 8) || (rev = MIN / 10 && pop > -9) 时,MIN <= f(rev,pop) <= MAX ;
Java源码
class Solution {
public int reverse(int x) {
if (x > -10 && x < 10) {
return 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;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Dart源码
int reverse(int x) {
if (x > -10 && x < 10) {
return x;
}
final num MAX_VALUE = pow(2, 31) - 1;
final num MIN_VALUE = -pow(2, 31);
int rev = 0;
while (x != 0) {
int pop = x % 10;
x = (x ~/ 10).toInt();
if (rev > MAX_VALUE / 10 || (rev == MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < MIN_VALUE / 10 || (rev == MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16