每日一题——整数反转

题目描述

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例:

1
2
3
4
5
6
7
8
9
10
11
#1:
输入: 123
输出: 321

#2:
输入: -123
输出: -321

#3
输入: 120
输出: 21

注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

思路

  • 本题如果不考虑溢出问题,是非常简单的。解决溢出问题有两个思路,第一个思路是通过字符串转换加 try catch 的方式来解决,第二个思路就是通过数学计算来解决。
  • 由于字符串转换的效率较低且使用较多库函数,所以解题方案不考虑该方法,而是通过数学计算来解决。
  • 通过循环将数字 x 的每一位拆开,在计算新值时每一步都判断是否溢出。
  • 溢出条件有两个,一个是大于整数最大值 MAX_VALUE,另一个是小于整数最小值 MIN_VALUE,设当前计算结果为 ans,下一位为 pop
  • ans * 10 + pop > MAX_VALUE 这个溢出条件来看
    • 当出现 ans > MAX_VALUE / 10 且 还有 pop 需要添加 时,则一定溢出
    • 当出现 ans == MAX_VALUE / 10pop > 7 时,则一定溢出,72^31 - 1 的个位数
  • ans * 10 + pop < MIN_VALUE 这个溢出条件来看
    • 当出现 ans < MIN_VALUE / 10 且 还有 pop 需要添加时,则一定溢出
    • 当出现 ans == MIN_VALUE / 10pop < -8 时,则一定溢出,8-2^31 的个位数

代码

PHP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 方法一
* @param Integer $x
* @return Integer
*/
function reverse($x) {
$y = 0;
if ($x < 0) {
$y = -abs(strrev($x)); // abs() 取绝对值
} else {
$y = strrev($x); // strrev() 反转字符串
}

if(pow(-2,31)>$y || $y>pow(2,31)-1){ // pow() 指数表达式
$y = 0;
}
return $y;
}

/**
* 方法二
* @param Integer $x
* @return Integer
*/
function reverse($x) {
$res = 0;
while($x != 0) {
$pop = $x % 10;
$x = ($x - $pop) / 10;
$res = $res * 10 + $pop;
}

if(pow(-2,31)>$res || $res>pow(2,31)-1){
$res = 0;
}
return $res;
}

Golang

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 方法一
func reverse(x int) int {
ret := 0
for x != 0 {
pop := x % 10
x /= 10
ret = ret*10 + pop // 实现 x 反转
if ret < math.MinInt32 || ret > math.MaxInt32 {
return 0
}
}
return ret
}

// 方法二
func reverse(x int) int {
y := 0
for x!=0 {
y = y*10 + x%10
if !( -(1<<31) <= y && y <= (1<<31)-1) {
return 0
}
x /= 10
}
return y
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!