Leetcode7_整数反转

题目

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

示例 1:

输入: 123
输出: 321


 示例 2:

输入: -123
输出: -321


示例 3:

输入: 120
输出: 21


注意:

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

 

 

解题要点

1.注意溢出: 超过最大值溢出 and  小于最小值溢出

 

 

图解算法

1.

2.

 

 

3.

 

 

 

 

 

 

解题思路

本题如果不考虑溢出问题,是非常简单的。解决溢出问题有两个思路,第一个思路是通过字符串转换加try catch的方式来解决,第二个思路就是通过数学计算来解决。

由于字符串转换的效率较低且使用较多库函数,所以解题方案不考虑该方法,而是通过数学计算来解决。


通过循环将数字x的每一位拆开(从个位向上拆)

注:例如x=123  则ans=3,pop=2

在计算新值时每一步都判断是否溢出。


溢出条件有两个,一个是大于整数最大值MAX_VALUE,另一个是小于整数最小值MIN_VALUE,设当前计算结果为ans,下一位为pop。

注:这里的大于整数最大值和小于整数最小值 指的是在取值范围内的最大最小值


从ans * 10 + pop > MAX_VALUE这个溢出条件来看
当出现 ans > MAX_VALUE / 10 且 还有pop需要添加 时,则一定溢出
当出现 ans == MAX_VALUE / 10 且 pop > 7 时,则一定溢出,7是2^31 - 1的个位数

注:这就是相当于最后的结果是32*10+1,这个值是否大于或者小于溢出的条件

从ans * 10 + pop < MIN_VALUE这个溢出条件来看
当出现 ans < MIN_VALUE / 10 且 还有pop需要添加 时,则一定溢出
当出现 ans == MIN_VALUE / 10 且 pop < -8 时,则一定溢出,8是-2^31的个位数

 

 

官方代码

直接看官方题解最佳

上面描述了为什么需要提前判断他们的数字,而不是把他们算出来后,其实就是为了防止溢出,所以需要事先检查这个语句是否会溢出

 

 1 class Solution {
 2 public:
 3     int reverse(int x) {
 4         int rev = 0;
 5         while (x != 0) {
 6             int pop = x % 10;
 7             x /= 10;
 8             if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0;
 9             if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0;
10             rev = rev * 10 + pop;
11         }
12         return rev;
13     }
14 };

 

 

官方代码改进版

如果不知道7 或者-8,可以直接计算出来,如下改动

 1 class Solution {
 2     public int reverse(int x) {
 3         int rev = 0;
 4         while(x != 0){
 5             int pop = x % 10;
 6             x = x / 10;
 7             if(rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > Integer.MAX_VALUE % 10)){
 8                 rev = 0;
 9                 break;
10             }else if(rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && x < Integer.MIN_VALUE % 10)){
11                 rev = 0;
12                 break;
13             }
14             rev = rev * 10 + pop;
15         }
16         return rev;
17     }
18 }

 

代码1(错误)

遇到的问题:

这段代码自己也能看懂,也明白是什么意思,也可以通过leetcode的测试样例

但是但是就是提交失败,原因是执行错误,在第6行处的Integer

 1 class Solution {
 2     public int reverse(int x) {
 3         int ans = 0;
 4         while (x != 0) {
 5             int pop = x % 10;
 6             if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7)) 
 7                 return 0;
 8             if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8)) 
 9                 return 0;
10             ans = ans * 10 + pop;
11             x /= 10;
12         }
13         return ans;
14     }
15 }

 

 

代码2(正确)

这段代码的作者说上面那个代码判断溢出是很丑陋的,原因在于需要记住末尾数字

两者都是在计算新值时每一步都提前判断是否溢出。

用时8ms,官方用时4ms

 1 class Solution {
 2 public:
 3     int reverse(int x) {
 4         int res = 0;
 5         while (x != 0) {
 6             if (res < INT_MIN/10) return 0;
 7             if (res > INT_MAX/10) return 0;
 8             res *= 10;
 9             int m = x % 10;
10             if (m < 0 && res < INT_MIN - m) return 0;
11             if (m > 0 && res > INT_MAX - m) return 0;
12             res += m;
13             x /= 10;
14         }
15         return res;
16     }
17 };

 

原题链接

7. 整数反转

 

 

参考链接

画解算法:7. 整数反转

整数反转

 

碎碎念

2019-09-20  00:05:47

今天的我还是太菜了,本来这道题是9.18的,但是自己只是大概看懂算法了,所以还没实现,今晚就实现了下

17,19号的leetcode还没有刷,每天一道的话,再加上今天20号

少了3道题

那么今天就要刷三道easy

冲鸭

转载于:https://www.cnblogs.com/vocoub/p/11538227.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值