整数反转及问题解析
Posted 打杂工程师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整数反转及问题解析相关的知识,希望对你有一定的参考价值。
一、算法题 LeetCode中有这样一个算法:
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
二、算法分析
- 个人解法
- 高人的解法
- 按照大神的思路,自己来实现的第一版
public static int reverse(int x)
int res=0;
while (x!=0)
res=res*10+x%10;
x=x/10;
return res;
问题:在程序运行的时候发现,如果入参的值比较大,如int值为-2^31时,会发生题目中所说的整数溢出情况。 所谓的整数溢出就是,整数值超出了int类型的最大范围。具体就是-2^31=-2147483648,当程序遍历到846384741之后,再将最后一位“2”反转的时候,反转后的值应该为-8463847412,此时的值超出了范围,最终的值变成了126087182。那么问题来了,为什么执行846384741*10的操作后结果为126087182?此处先卖一个关子,稍后再解释。
2. 第二版
public static int reverse(int x)
long res=0;
while (x!=0)
res=res*10+x%10;
x=x/10;
return ((int) res) == res ? (int)res:0;
在程序中首先通过long类型来处理数据,防止整数溢出问题,最后通过long类型和int类型转换来判断是否发生了溢出。
四、遇到的问题- 现在回答刚刚的问题“为什么执行846384741*10的操作后结果为126087182?”
- 将5和3分别转化成二进制,0101和0011
- 由于乘数3的二进制表示中,只有第0位和第1位是“1”,所以对被乘数分别左移0位和1位,得到的结果为0101和1010
- 将左移后的数相加,得到1111,转化成十进制就是15
- java int溢出,结果只会保留低32位,高位会抛弃掉:h ttps://blog.csdn.net/u010002184/article/details/86368598
- java int溢出总结: https://njucz.github.io/2017/08/16/java-int%E6%BA%A2%E5%87%BA%E6%80%BB%E7%BB%93/
- 计算机计算乘除法的原理: https://blog.csdn.net/qq_40316686/article/details/78370204
以上是关于整数反转及问题解析的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 力扣7. Reverse Integer 整数反转 Java 解法