LeetCode 第 8 题:String to Integer (atoi)
是一道看起来简单,但细节极多的经典题目。
这道题并不考复杂算法,而是非常考验:
- 规则拆解能力
- 边界条件意识
- 对整数溢出的理解
本文将围绕一份标准 Java 实现,系统讲清楚这道题的解题思路与设计细节。
一、题目规则拆解
题目要求我们模拟 C/C++ 中的 atoi 行为,将字符串转换为 32 位有符号整数。
转换规则如下:
- 忽略字符串前导空格
- 可选的正负号
+或- - 读取连续的数字字符
- 遇到非数字字符立即停止解析
- 若数值超出
int范围,需要进行截断 - 若无法转换,返回
0
重点在于:不是调用库函数,而是完整手写解析逻辑。
二、推荐实现代码(核心版本)
class Solution {
public int myAtoi(String s) {
int i = 0;
int n = s.length();
int sign = 1;
int res = 0;
// 跳过前导空格
while (i < n && s.charAt(i) == ' ') {
i++;
}
// 处理正负号
if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) {
sign = s.charAt(i) == '-' ? -1 : 1;
i++;
}
// 读取数字
while (i < n && Character.isDigit(s.charAt(i))) {
int digit = s.charAt(i) - '0';
// 溢出判断
if (res > Integer.MAX_VALUE / 10 ||
(res == Integer.MAX_VALUE / 10 && digit > 7)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
res = res * 10 + digit;
i++;
}
return res * sign;
}
}
三、为什么要先跳过空格?
while (i < n && s.charAt(i) == ' ') {
i++;
}
这是为了处理类似以下输入:
" -42"
如果不跳过空格,后续逻辑会直接失败。
四、为什么符号要单独处理?
int sign = 1;
if (s.charAt(i) == '-') sign = -1;
这是一个非常重要的设计点:
- 数字解析阶段只处理“无符号整数”
- 正负信息由
sign单独控制
这样做的好处是:
- 简化数值构建逻辑
- 为后续统一的溢出判断打下基础
五、digit = s.charAt(i) - '0' 的意义
int digit = s.charAt(i) - '0';
这是字符转整数的标准写法。
原理是 ASCII 编码连续:
'0' -> 48
'1' -> 49
...
'9' -> 57
因此字符减 '0',即可得到对应的数值。
六、溢出判断为什么要提前?
核心代码如下:
if (res > Integer.MAX_VALUE / 10 ||
(res == Integer.MAX_VALUE / 10 && digit > 7)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
为什么不能先计算再判断?
因为一旦执行:
res = res * 10 + digit;
如果发生溢出,res 本身已经不可信了。
正确做法必须是在乘 10 之前判断是否会溢出。
七、为什么只判断上限,不判断下限?
这是这道题中最容易被忽略、但最巧妙的设计点。
原因如下:
-
res始终为非负数 -
负号由
sign控制 -
一旦发生正数上溢:
- 正号 → 返回
Integer.MAX_VALUE - 负号 → 返回
Integer.MIN_VALUE
- 正号 → 返回
也就是说:
正数上溢,本质上已经覆盖了负数下溢的情况。
八、示例说明
输入:
"-2147483649"
执行过程:
- 解析符号,
sign = -1 - 数字解析到
214748364 - 下一位数字为
9 - 触发溢出判断
- 返回
Integer.MIN_VALUE
结果完全符合题意。
九、为什么不直接用 long?
确实可以使用 long 来规避溢出,但不推荐:
- 偏离题目考察重点
- 面试时容易被追问
- 学不到真正的边界控制能力
这道题的价值,恰恰在于用 int 写对溢出判断。
十、这道题真正考察的能力
- 字符串解析能力
- 状态管理与流程控制
- 整数边界与溢出意识
- 代码鲁棒性设计
这不是一道算法题,而是一道非常典型的工程题。
总结
atoi 的难点不在转换,而在于规则拆解与边界控制。
当你能从容写出这道题时,说明你已经对整数安全和输入解析有了扎实理解。