7 整数反转 字符串法详解(C++)

LeetCode 7. 整数反转:字符串反转法详解

题目描述

给你一个 32 位的有符号整数 x,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [-2³¹, 2³¹ - 1],就返回 0。假设环境不允许存储 64 位整数(有符号或无符号)。

图1:题目描述

示例说明

示例输入x输出解释
1123321正常反转
2-123-321保留负号,反转数字部分
312021反转后忽略前导零
400零的反转仍是零

图2:示例说明

解题思路:字符串反转法

核心思想

将整数转换为字符串,通过字符串反转操作实现数字反转,然后处理负号和溢出情况。这种方法避免了复杂的数学运算,实现简单直观。

步骤概述

  1. 将整数转换为字符串
  2. 处理负号(如有)
  3. 反转数字部分字符串
  4. 转换回整数并检查溢出
  5. 返回结果或0(溢出情况)

代码解析

完整代码(带注释)

#include <string>
#include <climits> // 包含INT_MAX和INT_MIN定义
using namespace std;

class Solution {
public:
    int reverse(int x) {
        // 步骤1:将整数转换为字符串
        string str = to_string(x);
        string result = "";
        int len = str.length();
        
        // 步骤2:处理负号
        if (str[0] == '-') {
            result += '-';  // 保留负号
            len--;          // 数字部分长度减1
            str.erase(0, 1); // 删除原负号
        }
        
        // 步骤3:反转数字部分字符串
        for (int i = len - 1; i >= 0; i--) {
            result += str[i];
        }
        
        // 步骤4:转换回长整数并检查溢出
        long long y = stoll(result); // 使用long long避免溢出
        if (y > INT_MAX || y < INT_MIN) {
            return 0; // 溢出则返回0
        }
        
        // 步骤5:返回结果
        return (int)y;
    }
};

// 测试用例
void test01() {
    Solution a;
    int x = 1534236469; // 该输入会导致反转后溢出
    cout << a.reverse(x) << endl; // 输出:0
}

int main() {
    test01();
    system("pause");
    return 0;
}

关键步骤解析

1. 字符串转换与负号处理
string str = to_string(x); // 将整数转换为字符串
if (str[0] == '-') {       // 检查是否为负数
    result += '-';          // 保留负号
    str.erase(0, 1);        // 移除原负号,只保留数字部分
}
  • 示例:x=-123 → str=“-123” → 处理后result=“-”,str=“123”
2. 字符串反转
for (int i = len - 1; i >= 0; i--) {
    result += str[i];
}
  • 示例:str=“123” → 循环从i=2开始,依次添加’3’、‘2’、‘1’ → result=“321”
3. 溢出检查
long long y = stoll(result); // 转换为长整数
if (y > INT_MAX || y < INT_MIN) {
    return 0; // 溢出处理
}
  • INT_MAX = 2147483647(2³¹-1)
  • INT_MIN = -2147483648(-2³¹)
  • 使用stoll而非stoi避免转换过程中溢出

代码执行步骤表格(测试用例跟踪)

以测试用例 x = 1534236469 为例,跟踪代码执行全过程:

步骤编号代码操作变量变化说明
1string str = to_string(x)str = “1534236469”整数转字符串
2检查str[0]是否为’-’str[0] = ‘1’,非负无需处理负号
3len = str.length()len = 10数字部分长度为10
4for循环反转字符串i从9到0依次添加字符 → result = “9646324351”字符串反转
5long long y = stoll(result)y = 9646324351转换为长整数
6`if (y > INT_MAXy < INT_MIN)`
7return 0返回0溢出情况处理

不同输入的处理结果对比

输入x字符串转换反转后字符串转换后数值是否溢出输出
123“123”“321”321321
-123“-123”“-321”-321-321
120“120”“021” → “21”2121
0“0”“0”00
1534236469“1534236469”“9646324351”96463243510

特别说明:示例3中"120"反转后得到"021",但通过stoll转换为整数时会自动忽略前导零,得到21。

复杂度分析

时间复杂度

  • O(N),其中N为整数x的位数。字符串转换和反转操作均需遍历所有位数。

图3:时间复杂度O(N)示意图

空间复杂度

  • O(N),存储转换后的字符串需要O(N)空间。

执行性能

在LeetCode上的执行结果:

  • 执行用时:0 ms,击败 100.00% 的C++提交
  • 内存消耗:9.41 MB,击败 6.40% 的C++提交

图4:执行用时分布

性能优势分析

  • 字符串操作简单直接,无复杂数学计算
  • 溢出检查逻辑清晰,一次比较即可判断
  • 代码简洁,无多余操作

注意事项与优化建议

注意事项

  1. 负号处理:必须保留负号且只保留一个
  2. 前导零:反转后可能出现的前导零会被整数转换自动忽略
  3. 溢出检查:必须使用比int范围更大的类型存储中间结果(如long long)

优化建议

  1. 原地反转:可以不使用字符串,直接通过数学运算(取余、乘10)实现反转,空间复杂度可降至O(1)
  2. 提前溢出检查:在数学运算过程中即可检查溢出,无需等到最后转换

题目链接

LeetCode 7. 整数反转

代码下载(VS2022)

https://wwbq.lanzn.com/iHOcL391fo2f
密码:4xgp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值