高效的算法来逆转32位整数

288 阅读3分钟

在这篇文章中,我们将探索一种高效的算法来逆转32位整数。这涉及到反向整数出界的边缘情况。

目录

  1. 问题陈述
  2. 反转一个数字的算法
  3. 伪代码
  4. 代码
  5. 解释
  6. 时间和空间的复杂性

让我们从反转一个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

所以,这也是一个特殊的情况。

伪代码

  1. 将数字N作为输入

  2. 检查N是否为INT32_MIN

    • 如果是:
      • print "我们不能在32位中存储这个数字的反转"
      • 回报
  3. define boolean isNegative = false

  4. 检查N是否为负数

  5. 如果是:

    • 则 isNegative = true
  6. 否则

    • isNegative = false
  7. while(N大于0)

    • 检查reverse是否>INT32_MAX/10
    • 如果是的话。
      • print "我们不能在32位中存储该数字的反向"
      • 返还
    • reverse = reverse*10 + N%10
    • N = N/10
  8. 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

  1. n= 214748364 ,反向:7
  2. n= 21474836 , 反向:74
  3. n= 2147483 , 反转:746
  4. n= 214748 , 反转:7463
  5. n= 21474 , 反面:74638
  6. n= 2147 , 反面:746384
  7. n= 214 , 反面:7463847
  8. n= 21 , 反面:74638474
  9. 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)
  • 因为要创建一个变量来存储反向数字