LeetCode算法题目_7

LeetCode算法题目_7

题目描述

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

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

解决方案

反转整数的方法可以与反转字符串进行类比。

我们想重复“弹出” xx 的最后一位数字,并将它“推入”到 \text{rev}rev 的后面。最后,\text{rev}rev 将与 xx 相反。

我的算法如下,考虑补码原码转换,不过没有加上溢出判断,并且在-2^31-1时会溢出。后续会调试更新。

int reverse(int x){
    
    int y = x>>31;
    int z = (x ^ y) - y;  //取原码
    int a[32];
    int index = 0;
    int flag = 0;
    if((z & 0x80000000) != 0)
    {
        flag = 1;
        z = z & 0x7fffffff;
    }
    int rev = 0;
        
    while(z != 0)
    {
        int pop = z % 10;
        z /= 10;
        if(flag == 0)
        {
            if (rev > 2147483647/10 || (rev == 2147483647 / 10 && pop > 7)) return 0;
        }
        else
        {
            if (rev < 2147483648/10 || (rev == 2147483648 / 10 && pop > 8)) return 0;
        }
        rev = rev * 10 + pop;
    }
    
    if(flag == 1)
    {
        rev = rev | 0x80000000;
    }
    
    y = rev>>31;
    rev = (rev ^ y) - y;  //取原码
    
    if(rev > 0xffffffff)
        return 0;
    else
        return rev;

}


下面介绍另一种简便算法。

int reverse(int x){
    /**
    ret 保存旧的翻转中间值, temp 保存新的翻转过程中间值
    依次提取 x 的末位加入 temp, 如果发生溢出则通过temp/10 
    无法得到上一轮的翻转结果 ret
    **/
    int ret = 0;
    while(x != 0) {
        long temp1 = ((long)ret*10) + x%10;
        int temp = (int)temp1;
        if(temp / 10 != ret)
            return 0;
        ret = temp;
        x /= 10;
    }
    return ret;
}

此方法会产生溢出由于该语句有可能造成int类型超限,故强制转换ret为long。ong temp1 = ((long)ret*10) + x%10;该算法思路很简洁。

下面介绍标准算法。

int reverse(int x){
    
    int z =x;
    int rev = 0;
        
    while(z != 0)
    {
        int pop = z % 10;
        z /= 10;
        
        if (rev > 2147483647/10 || (rev == 2147483647 / 10 && pop > 7)) return 0;
        
        if (rev < -2147483648/10 || (rev == -2147483648 / 10 && pop < -8)) return 0;
        
        rev = rev * 10 + pop;
    }
    
    
    return rev;

}

此算法判断溢出考虑到:MAX_VALUE : 2147483647 MIN_VALUE : -2147483648 。要判断最后一位不要大于 7 和 不要小于-8。

另一种简便算法,利用long类型做运算,先反转,最后判断溢出。

int reverse(int x)
{
    int max = 0x7fffffff, min = 0x80000000;//int的最大值最小值
    long rs = 0;//用long类型判断溢出
    for(;x;rs = rs*10+x%10,x/=10);//逆序,正负通吃,不用单独考虑负值
    return rs>max||rs

你可能感兴趣的:(LeetCode算法练习)