
Day 4。
今天两道题都和 整数处理、字符串转数字、边界判断 有关。
看起来像“模拟题”,但实际上非常考验细节,一不小心就会翻车。
今天的关键词是:反转、溢出、符号处理、模拟细节。
🧠 LeetCode 7 – Reverse Integer
💡 思路总结
这题要求把一个整数的数字反转。
比如:
123→321-123→-321120→21
最直接的思路就是不断取出最后一位,再拼到新数后面。
核心操作:
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)
💡 思路总结
这题是一个非常典型的字符串模拟题。
题目要求把字符串转换成整数,但过程不是直接调函数,而是按规则一步一步处理:
- 跳过前导空格
- 处理正负号
- 读取连续数字
- 遇到非数字就停止
- 判断是否溢出
💻 代码实现
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 天
