7. 整数反转 C++版

LeetCode 7. 整数反转

Posted by Twany on November 12, 2019

题目概述

  • 题号1. 两数之和

  • 难度:简单

  • 内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
      
    示例 1:
      
    输入: 123
    输出: 321
     示例 2:
      
    输入: -123
    输出: -321
    示例 3:
      
    输入: 120
    输出: 21
    注意:
      
    假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
      
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/reverse-integer
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    

第一次思路

直接循环求商求余,反向乘!

要做此题,最基本的就是对 %/ 以及数的位关系的理解。

  • 以365为例,第一次求余数:365%10 = 5,那么这个5就应该是反转数的首位。
  • 365/10 = 36,再次36%10 = 6,这次我们应该 把 5 和 6 组建成 56,也就是5*10 + 6 = 56
  • 36/10 = 3,再次3%10 = 3,这次我们应该 把 56 和 3 组建成 563,也就是56*10 + 3 = 563

由上述过程我们可以总结归纳出,每次先求出原数的10的余数,然后将原数除以10得到商,结果和余数相乘并加上商,就是我们要的反转数

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
int reverse7(int x)
{
	int revNum = 0;
	int pop = 0;
	while (x != 0)
	{
		pop = x % 10;
		revNum = revNum * 10 + pop;
		x /= 10;
	}

	return revNum;
}

测试 Submit

分析

看报错信息可以晓得:溢出了 ,题中给出了要求:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数 溢出那么就返回 0

改进

此处我们要注意溢出的问题

temp=rev⋅10+pop 时会导致溢出。

幸运的是,事先检查这个语句是否会导致溢出很容易。

为了便于解释,我们假设 rev 是正数。

  • 如果 temp=rev⋅10+pop 使得溢出,那么一定会有 rev > INTMAX/10;

至于 7-8 是怎么产生的?

以 7 为例:题中要求的最大值是 2^31 − 1,这是int类型的最大值,为 2147483648,当 rev = INTMAX/10,此时 rev = 2147483640,在加上8就溢出了,所以进行控制。

改进Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int reverse7(int x)
{
	int revNum = 0;
	int pop = 0;
	while (x != 0)
	{
		pop = x % 10;
		revNum = revNum * 10 + pop;
		x /= 10;

		// 溢出判断
		if (revNum > INT_MAX / 10 || (revNum == INT_MAX / 10 && pop > 7))
			return 0;
		if (revNum < INT_MIN / 10 || (revNum == INT_MIN / 10 && pop < -8))
			return 0;
	}

	return revNum;
}

改进Submit

收获总结

题很简单,需要注意的是溢出问题。而判断是否溢出有需要去考虑关键位的大小,很细节