整数反转及问题解析

一、算法题
    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.youkuaiyun.com/u010002184/article/details/86368598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值