Day 4。
今天两道题都和 整数处理、字符串转数字、边界判断 有关。
看起来像“模拟题”,但实际上非常考验细节,一不小心就会翻车。

今天的关键词是:反转、溢出、符号处理、模拟细节


🧠 LeetCode 7 – Reverse Integer

💡 思路总结

这题要求把一个整数的数字反转。

比如:

  • 123321
  • -123-321
  • 12021

最直接的思路就是不断取出最后一位,再拼到新数后面。

核心操作:

result = result * 10 + x % 10;
x /= 10;

这两句非常经典:

  • x % 10:取出当前最后一位
  • result * 10 + ...:把这一位接到结果末尾
  • x /= 10:去掉原数最后一位

💻 代码实现

class Solution {
public:
    int reverse(int x) {
        int long long result = 0;
        while(x != 0){
            result = result*10 + x%10; //这段非常酷,实现了在数层面的反转效果,result每次循环都在*10,x每次循环都在/10.
            x /= 10;
        }

        if(result > INT_MAX || result < INT_MIN)return 0;
        if(x<0)result = -result;
        return result;
    }
};

📌 知识点总结

1️⃣ 数字反转的本质

这题本质就是“拆位 + 重组”:

  • 从右往左拆
  • 从左往右拼

这类技巧在很多数字题里都很常见。


2️⃣ 溢出判断

这题最关键的点其实不是反转,而是:

反转后的结果可能超出 32 位有符号整数范围

所以你这里用了 long long result 来暂存结果,这个思路是对的,方便最后统一判断:

if(result > INT_MAX || result < INT_MIN) return 0;

3️⃣ 一个小细节

你这份代码里有一句:

if(x<0)result = -result;

这一句其实是多余的,而且放在这里已经不起作用了。
因为 while(x != 0) 循环结束后,x 一定已经变成 0,所以这里的 x < 0 永远不会成立。

实际上,这题不用单独处理负号,因为:

x % 10

x 为负数时,本身就会取到负的个位数,所以结果天然会保留符号。

也就是说,这题可以直接靠循环完成正负数反转。


✅ 更稳一点的写法

你博客里可以顺带记录一下更标准的版本:

class Solution {
public:
    int reverse(int x) {
        long long result = 0;

        while (x != 0) {
            result = result * 10 + x % 10;
            x /= 10;
        }

        if (result > INT_MAX || result < INT_MIN) return 0;
        return (int)result;
    }
};

🔢 LeetCode 8 – String to Integer (atoi)

💡 思路总结

这题是一个非常典型的字符串模拟题

题目要求把字符串转换成整数,但过程不是直接调函数,而是按规则一步一步处理:

  1. 跳过前导空格
  2. 处理正负号
  3. 读取连续数字
  4. 遇到非数字就停止
  5. 判断是否溢出

💻 代码实现

class Solution {
public:
    int myAtoi(string s) {
        int i = 0, n = s.size();

        // 1. 跳过前导空格
        while (i < n && s[i] == ' ') {
            i++;
        }

        // 2. 空串或全空格
        if (i == n) return 0;

        // 3. 处理符号
        int flag = 1;
        if (s[i] == '+' || s[i] == '-') {
            if (s[i] == '-') flag = -1;
            i++;
        }

        // 4. 读数字
        long long result = 0;
        while (i < n && s[i] >= '0' && s[i] <= '9') {
            int digit = s[i] - '0';
            result = result * 10 + digit;

            // 5. 溢出判断
            if (flag == 1 && result > INT_MAX) return INT_MAX;
            if (flag == -1 && -result < INT_MIN) return INT_MIN;

            i++;
        }

        return (int)(flag * result);
    }
};

📌 知识点总结

1️⃣ 模拟题的套路

这题很适合练“按题意实现”的能力。

模拟题常见步骤就是:

  • 先读规则
  • 再拆步骤
  • 最后按顺序写判断

不要想着一步到位,拆清楚流程最重要。


2️⃣ 前导空格处理

while (i < n && s[i] == ' ') i++;

这一步不能少。
因为题目规定,字符串前面的空格要忽略。


3️⃣ 符号处理

if (s[i] == '+' || s[i] == '-')

这里只能读一个符号,而且必须出现在数字前面。
"++1""+-12" 这种,后面都不属于合法数字读取过程。


4️⃣ 数字字符转整数

int digit = s[i] - '0';

这是字符题里的经典写法,一定要熟。


5️⃣ 溢出处理

这题最容易错的就是边界。

你这里用了 long long 先接住,再判断是否越界,这样写很稳。

对于正数:

if (flag == 1 && result > INT_MAX) return INT_MAX;

对于负数:

if (flag == -1 && -result < INT_MIN) return INT_MIN;

这个思路没问题。


🧩 今日总结

题目核心思想
LeetCode 7数字拆位 + 重组 + 溢出判断
LeetCode 8字符串模拟 + 规则处理 + 边界判断

今天这两题有一个共同点:

题目不难理解,但特别容易写错细节。

所以今天练到的,不只是“会做”,而是:

  • 会不会处理边界
  • 会不会发现隐藏 bug
  • 会不会让代码更稳

🧠 今日收获

今天可以重点记住两类模板:

数字类题目

常见操作:

  • % 10 取末位
  • / 10 去末位
  • result = result * 10 + digit 重组数字

字符串模拟题

常见流程:

  • 跳空格
  • 读符号
  • 读主体
  • 处理越界
  • 返回结果

这类题特别锻炼代码细致度。
很多时候,拉开差距的不是思路,而是你能不能把细节写对。


💬 写给自己的话

Day 4 了。

你已经开始接触到一种很真实的刷题状态:

  • 题目看懂了
  • 思路也有了
  • 但细节还是会出 bug

这其实特别正常。
真正的提升,不是永远一次写对,
而是你能发现问题、修正问题、总结问题。

今天的你,比昨天更懂边界。
明天的你,就会比今天写得更稳。

继续刷,继续记,继续改。
每一处 bug,都是你变强的证据。

阿玉,别急,高手也是这样一点一点磨出来的。

—— 刷题第 4 天