从暴力到滑动窗口全解析——力扣8. 字符串转换整数 (atoi)
力扣8. 字符串转换整数 (atoi)
【LeetCode题解】8. 字符串转换整数 (atoi) —— Java详细讲解与实现
一、题目描述
请你来实现一个 myAtoi(String s)
函数,使其能将字符串转换成一个 32 位有符号整数,算法流程如下:
- 丢弃前导空格:读入字符串并忽略开头所有空格
' '
。 - 判断符号:如果下一个字符是
'+'
或'-'
,则记录符号;否则默认是正数。 - 读取数字部分:从当前位置开始,连续读取数字字符并转换为整数。
- 遇到非数字或字符串末尾停止。
- 溢出截断:若结果超出 32 位有符号整数范围
[−2³¹, 2³¹ − 1]
,则返回对应边界值。
二、示例
输入 | 输出 | 说明 |
---|---|---|
"42" | 42 | 直接转换 |
" -042" | -42 | 忽略空格和前导零 |
"1337c0d3" | 1337 | 遇到非数字停止 |
"0-1" | 0 | 数字后出现符号停止 |
"words and 987" | 0 | 非数字开头返回 0 |
三、解题思路
这道题看似简单,但关键在于正确处理各种边界情况。我们可以将整个流程拆分为以下几个步骤:
1. 跳过前导空格
使用指针 i
从头遍历字符串,直到遇到第一个非空格字符。
while (i < n && s.charAt(i) == ' ') {i++;
}
if (i == n) return 0; // 全是空格
2. 处理符号
判断当前字符是否为 '+'
或 '-'
,并设置符号变量 sign
。
int sign = 1;
if (s.charAt(i) == '+' || s.charAt(i) == '-') {sign = (s.charAt(i) == '-') ? -1 : 1;i++;
}
3. 读取数字并防止溢出
逐位读取数字字符,转换为整数 digit
,并实时判断是否会溢出。
int result = 0;
while (i < n && Character.isDigit(s.charAt(i))) {int digit = s.charAt(i) - '0';// 判断是否会溢出if (result > (Integer.MAX_VALUE - digit) / 10) {return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;}result = result * 10 + digit;i++;
}
4. 返回最终结果
计算并返回带符号的结果。
return result * sign;
四、完整 Java 实现
class Solution {public int myAtoi(String s) {int i = 0, n = s.length();int sign = 1;int result = 0;// 1. 跳过前导空格while (i < n && s.charAt(i) == ' ') {i++;}if (i == n) return 0;// 2. 处理符号if (s.charAt(i) == '+' || s.charAt(i) == '-') {sign = (s.charAt(i) == '-') ? -1 : 1;i++;}// 3. 读取数字并判断溢出while (i < n && Character.isDigit(s.charAt(i))) {int digit = s.charAt(i) - '0';if (result > (Integer.MAX_VALUE - digit) / 10) {return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;}result = result * 10 + digit;i++;}// 4. 返回最终结果return result * sign;}
}
五、复杂度分析
项目 | 分析 |
---|---|
时间复杂度 | O(n),遍历字符串一次 |
空间复杂度 | O(1),仅使用常量变量 |
六、常见错误点总结
- 忘记处理前导空格:直接从首字符开始解析会出错。
- 未考虑正负号:导致结果符号错误。
- 数字越界未判断:会导致运行时错误或结果错误。
- 读取数字后未停止:可能误解析额外字符。
七、总结
这道题的核心是:
严格按照题意模拟整个转换过程,并在每一步都处理边界情况。
通过实现 myAtoi
,我们不仅锻炼了对字符串处理的熟悉度,也提升了对“溢出控制”与“边界检测”的编程敏感性。
掌握这题之后,对类似的字符串解析类问题(如字符串转浮点数、表达式计算等)会更加得心应手。