【刷题之路】NC57 反转数字

文章介绍了如何解决一个编程问题,即反转32位有符号整数,同时处理溢出的情况。在解题过程中,首先提出通过循环拆分数字并判断溢出的思路,然后给出初步的代码实现,接着分析了在特定情况下可能出现的溢出错误,并提出了改进的溢出判断条件,最后给出了修正后的代码实现。
摘要由CSDN通过智能技术生成

一、题目描述

原题连接: NC57 反转数字

题目描述:
给定一个32位的有符号整数num,将num中的数字部分反转,最后返回反转的结果
1.只反转数字部分,符号位部分不反转
2.反转后整数num超过 32 位的有符号整数的范围 [−231, 231 − 1] ,返回 0
3.假设本题不允许存储 64 位整数(有符号或无符号,即C++不能使用long long ,Java不能使用long等)

数据范围:
-2^31 <= x <= 2 ^31 - 1

示例1
输入:
12
返回值:
21

示例2
输入:
-123
返回值:
-321

示例3
输入:
10
返回值:
1

示例4
输入:
1147483649
返回值:
0

二、解题

方法——数字法

1、思路解析

先通过循环把数字的每一位拆开,在计算时候每一步都判断是否溢出,若溢出就直接返回0,否则进行下一轮循环。
我们使用一个变量ans来存储最终结果
我们从末尾开始取数字,用一个变量next来存储下一位
让ans累计操作:ans = ans * 10 + next即可算出最终结果。

2、代码实现

有了以上思路,那我们写起代码来也就水到渠成了:

int reverse(int x) {
	// 当x介于(-10, 10)之间时,反转后还是等于自身
	if (x > -10 && x < 10) {
		return x;
	}
	int ans = 0;
	while (x) {
		int next = x % 10;
		ans = ans * 10 + next;
		x /= 10;
	}
	// 进行判断
	if (ans < INT_MIN || ans > INT_MAX) {
		return 0;
	}
	return ans;
}

这样看似已经完成了,但是如果你把这段代码提交到牛客网上是,就会看到:
在这里插入图片描述
我们在看它的提示:
在这里插入图片描述
我们仔细思考之后发现,还是溢出导致的问题,那是为什么呢?不是已经在每一步都判断了是否溢出了吗?怎么还会出现溢出问题呢?
其实,我们都忽略了一点,就是当一个类型的数据要存储一个超出此类型的最大值的数的时候,就会发生“截断”。例如我们知道一个unsigned char类型的变量可存储的最大值是255,若非要让它存储253 + 8,那就只能发生截断:
在这里插入图片描述
也就是说存入变量的是一个比最大数要小的数字了,这时候判断就会出错了。
类似的有符号数在溢出时会变成负数也是类似的原理。

所以我们要做的应该是提前判断
因为ans每次都要乘上10,所以我们应该提前一位就判断了:
若ans为正数:
1、当出现ans > INT_MAX / 10 且还有next添加时,则一定溢出了。
2、当出现ans == INT_MAX / 10且next > 7时,则一定溢出了。(7是INT_MAX的最后一位)

若ans为负数:
1、当出现ans < INT_MIN / 10且后面还有next添加时,则一定溢出。
2、当出现ans == INT_MIN / 10且next < -8时,则一定溢出。(8是INT_MIN的最后一位)

有了以上思路,那我们在写起代码来也就水到渠成了:

int reverse(int x) {
    if (x > -10 && x < 10) {
        return x;
    }
    int ans = 0;
    while (x) {
        int next = x % 10;
        if (ans > INT_MAX / 10 || (ans == INT_MAX / 10 && next > 7)) {
            return 0;
        } else if (ans < INT_MIN / 10 || (ans == INT_MIN / 10 && next < -8)) {
            return 0;
        }
        ans = ans * 10 + next;
        x /= 10;
    }
    return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林先生-1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值