整数反转及问题解析

Posted 打杂工程师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整数反转及问题解析相关的知识,希望对你有一定的参考价值。

一、算法题     LeetCode中有这样一个算法:
    
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。


示例 1:
    输入: 123
    输出: 321

示例 2:
    输入: -123
    输出: -321

示例 3:
    输入: 120
    输出: 21
注意:

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

 

二、算法分析
  1.     个人解法
当第一次看到这个算法的时候,其实是不知道该如何做的,自己勉强使用了最笨的办法来实现,大致思路是,首先将int类型的整数变为字符串,然后通过不断的截取字符串来实现整数的反转,反转后的值先用long来接收,然后判断是否溢出了int的最大范围,最后将值再转换成int类型。
  1. 高人的解法
直接看图了:

其大致的思路就是通过不断递归整数整除10取余来获取最后一位数字,从而实现整体的整数的反转。   三、算法实现
  1. 按照大神的思路,自己来实现的第一版

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类型转换来判断是否发生了溢出。

    四、遇到的问题
  1. 现在回答刚刚的问题“为什么执行846384741*10的操作后结果为126087182?”
这个需要从计算机的原理说起,在计算机中,乘法和除法运算是通过位移运算的到的。而针对我们这次的乘法运算就是通过对被乘数做 左移来实现的。举个例子,比如:5*3,在计算机中的实现如下:
  • 将5和3分别转化成二进制,0101和0011
  • 由于乘数3的二进制表示中,只有第0位和第1位是“1”,所以对被乘数分别左移0位和1位,得到的结果为0101和1010
  • 将左移后的数相加,得到1111,转化成十进制就是15
针对本次问题中,846384741*10,转化成二进制为:11001101100011010011000110011011和1010,所以对被乘数左移1位和3位得到110011011000110100110001100110110和11001101100011010011000110011011000,两个二进制值相加的结果为100000000111100000111111000000001110, 由于此时的结果已经超过了int类型的范围,所以计算机将默认截取后32位,即00000000111100000111111000000001110,此时将值转换为十进制后为:126087182   五、参考资料
  1. java int溢出,结果只会保留低32位,高位会抛弃掉:h ttps://blog.csdn.net/u010002184/article/details/86368598
  2. java int溢出总结: https://njucz.github.io/2017/08/16/java-int%E6%BA%A2%E5%87%BA%E6%80%BB%E7%BB%93/
  3. 计算机计算乘除法的原理: https://blog.csdn.net/qq_40316686/article/details/78370204

以上是关于整数反转及问题解析的主要内容,如果未能解决你的问题,请参考以下文章

前端与算法 leetcode 7. 整数反转

LeetCode 力扣7. Reverse Integer 整数反转 Java 解法

LeetCode 力扣7. Reverse Integer 整数反转 Java 解法

7. Reverse Integer 反转整数

letcode 7 整数反转

LeetCode7. 整数反转