力扣7.整数反转的两种算法详解

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−2 ^31, 2 ^31 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

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

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

示例 3:
输入:x = 120
输出:21

示例 4:
输入:x = 0
输出:0

提示:

-2 ^31 <= x <= 2 ^31 - 1

算法一、(不考虑储存64位整数):字符串翻转

#include <iostream>
#include <string>
#include <algorithm>
#include <climits>

class Solution {
public:
    int reverse(int x) {
        // 将整数转换为字符串
        std::string str = std::to_string(x);
        
        // 处理负号
        if (x < 0) {
            std::reverse(str.begin() + 1, str.end());
        } else {
            std::reverse(str.begin(), str.end());
        }
        
        // 将反转后的字符串转换回整数
        long rev = std::stoll(str);
        
        // 检查是否超出32位有符号整数范围
        if (rev > INT_MAX || rev < INT_MIN) {
            return 0;
        }
        
        return static_cast<int>(rev);
    }
};

不考虑不能储存64位整数的情况比较简单,不多赘述。

算法二:数学方法

完整代码如下:

class Solution {
public:
    int reverse(int x) {
        int max = 2147483647;
        int min = -2147483648;
        int rev = 0;
        while(x != 0){
            if(rev > max / 10 || rev < min / 10){
                return 0;
            }
            int digit = x % 10;
            x /= 10;
            rev  = rev * 10 + digit;
            
        }
        return rev;
    }

解析
第一步是将整形进行翻转:

// 弹出 x 的末尾数字 digit
digit = x % 10
x /= 10

// 将数字 digit 推入 rev 末尾
rev = rev * 10 + digit

由于x是一个32位整数,所以为了避免溢出,需要在最后一次计算rev前,判断是否反转后的结果会超过32 位有符号整数的范围 [−2 ^31, 2 ^31−1]

由于题目要求环境不能储存64位整数,所以不能直接−2 ^ 31 ≤ rev⋅10+digit ≤2 ^ 31 −1
所以需要采取一些数学方法来使在计算过程中,不出现超过32位整数的值。在这里可以对边界值进行分解。记:

min =2 ^31 = -2147483648;
max = 2 ^311 = 2147483647;

进行分解:
min = (min/10) * 10 - 8;
max = (max/10) * 10 + 7;

当x>0的时候,
rev * 10 + digit <= (max/10) * 10 + 7
=>
(rev - max/10)*10 <= 7 - digit;

当rev < max/10的时候:
即digit <= 17时可以成立,由于digit<=9,所以等式一直成立。

当rev = max/10的时候:
digit <= 7;
此时x如果还能被拆解,说明x的位数和max一样,而此时digit为x的最高位,又因为x <= 2 ^31 - 1 = 2147483647, 所以x的最高位为2,也就是digit<=2,所以等式恒成立。

当rev > max/10的时候:
由于此时分析的是x>0时候的情况,所以这种情况不成立。

所以可以化简为 x <= max/10,所以在代码中,当x>max/10的时候,可以return 0;


接下来分析x<0时候的情况也是同理即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值