在这篇文章中,我们将探索一种高效的算法来逆转32位整数。这涉及到反向整数出界的边缘情况。
目录
- 问题陈述
- 反转一个数字的算法
- 伪代码
- 代码
- 解释
- 时间和空间的复杂性
让我们从反转一个32位整数开始。
问题说明
给定一个32位的数字,我们必须把这个32位整数的数字倒过来,然后打印倒过来的32位数字。
例子:
输入:34924
输出:42943
输入:-93432
输出:-23439
反转一个数字的算法
这个问题的实现很简单,
我们将运行一个while循环,直到数字大于0,在while循环中我们将运行以下代码
-
reverseNo = reverseNo*10 + n的最后一位数字
-
通过除以10来减少数字
-
如果数字是负数,那么我们可以通过使其成为正数来逆转数字,最后我们可以用-1乘以该数字,将其转换为负数。
-
但是,我们在这里有边缘情况 ,因为问题中提到倒数也是32位 ,所以我们需要检查倒数是否可以存储在32位int中。
-
如果我们可以将倒数存储在32位,那么我们将打印这个数字,否则我们将打印 "不能将倒数存储在32位"
-
另外,如果N是INT_MIN(-2147483648),那么由于数字是负数,我们可以通过与-1相乘将任何负数转换为正数 ,但是这里N的正数是2147483648,可以存储在int中,因为int的最大范围是2147483647
所以,这也是一个特殊的情况。
伪代码
-
将数字N作为输入
-
检查N是否为INT32_MIN
- 如果是:
- print "我们不能在32位中存储这个数字的反转"
- 回报
- 如果是:
-
define boolean isNegative = false
-
检查N是否为负数
-
如果是:
- 则 isNegative = true
-
否则
- isNegative = false
-
while(N大于0)
- 检查reverse是否>INT32_MAX/10
- 如果是的话。
- print "我们不能在32位中存储该数字的反向"
- 返还
- reverse = reverse*10 + N%10
- N = N/10
-
print reverse
代码
以下是用C++实现的:
#include<bits/stdc++.h>
using namespace std;
void solve() {
int n, reverse=0; cin>>n;
if(n==INT_MIN) {
cout<<"reverse number can't be stored in 32 bits"<<endl;
return;
}
bool isNegative = false;
if(n<0) isNegative = true, n=-1*n;
while(n>0) {
if(reverse>INT32_MAX/10) {
cout<<"reverse number can't be stored in 32 bits"<<endl;
return;
}
reverse = reverse*10 + n%10;
n /= 10;
}
if(isNegative) cout<<-1*reverse<<endl;
else cout<<reverse<<endl;
}
int main() {
solve();
return 0;
}
输入1
-746384741
输出1
-147483647
输入2
2147483647
输出2
reverse number can't be stored in 32 bits
解释
让N = INT32_MAX = 2147483647
- 首先,我们将检查数字是否是
INT_MIN,因为它不是,然后继续前进。 - 因为数字是正数,所以
isNegative = false - 然后我们将运行while循环
- 在while循环中,首先我们将检查数字是否大于
INT_MAX/10
在执行reverse*10 + n%10 操作之前,之所以这样做并写下这个,是因为
如果数字大于INT_MAX/10 ,如果我们把这个数字乘以10
,那么它可以被存储在int中,所以它将被溢出
例如:
如果任何intK = 2147483647 大于INT_MAX/10=2147483647/10=214748364
,如果我们将其乘以10:K = K * 10;
那么如果我们打印K,那么它将显示K = -2147483626 在C++中
因此,它被溢出 ,所以我们需要首先检查N > INT_MAX/10,如果它大于INT_MAX/10 ,那么我们将直接中断循环。如果N < = INT_MAX/10 ,那么我们就可以进行进一步的迭代对于N => INT32_MAX => 2147483647 ,以下是10次迭代的结果
最初:n= 2147483647 , reverse: 0
- n= 214748364 ,反向:7
- n= 21474836 , 反向:74
- n= 2147483 , 反转:746
- n= 214748 , 反转:7463
- n= 21474 , 反面:74638
- n= 2147 , 反面:746384
- n= 214 , 反面:7463847
- n= 21 , 反面:74638474
- n= 2 , 反面:746384741
在10th 迭代中,当n= 2 , reverse: 746384741
,我们将检查(reverse > INT_MAX/10) => (746384741 > 2147483647/10),所以答案为真
因此,我们将打破循环并打印 "我们不能逆转这个数字,因为我们不能在int中存储N的反向"。
我们都知道,如果我们在不检查的情况下进行操作,reverse*10+n%10。
则:
reverse = -1126087180
因此,如果我们在没有检查的情况下进行操作,反向将被溢出。
时间和空间复杂度
时间复杂度
- O(数字中的位数)
- 因为我们正在遍历循环,直到所有的数字都被访问完。
空间复杂度
- O(1)
- 因为要创建一个变量来存储反向数字