LeetCode 8. 字符串转换整数 (atoi)
题目描述
思路分析
解法一:模拟(推荐)
核心思路:
按照题目描述逐步处理字符串,关键是正确处理 4 个步骤的顺序和溢出判断:
- 跳过前导空格:
while s[i] == ' '- 判断符号位:
'+'或'-',默认为正- 逐位读取数字:
while s[i] in ['0'..'9'],res = res * 10 + digit- 溢出处理:数字超过
INT_MAX (2^31-1)时截断返回边界值溢出判断技巧:
- 在累加前判断:若
res > (INT_MAX - digit) / 10,说明再累加就会溢出- 或在累加后判断:
res > INT_MAX(使用long类型承接)遇到非数字字符立即停止,不报错(如
"4193 with words"→4193)。
复杂度分析:
- 时间复杂度:O(n),其中 n 为字符串长度,最多遍历一次
- 空间复杂度:O(1),仅使用常数额外空间
class Solution {
public int myAtoi(String s) {
int i = 0, n = s.length();
int sign = 1;
long res = 0;
// 1. 去除前导空格
while (i < n && s.charAt(i) == ' ') {
i++;
}
// 2. 判断符号
if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) {
if (s.charAt(i) == '-') {
sign = -1;
}
i++;
}
// 3. 逐位读取数字,处理溢出
while (i < n && Character.isDigit(s.charAt(i))) {
res = res * 10 + (s.charAt(i) - '0');
if (res > Integer.MAX_VALUE) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
i++;
}
return (int) (sign * res);
}
}
func myAtoi(s string) int {
var res int
sign := 1
i := 0
// 1. 去除前导空格
for i < len(s) && s[i] == ' ' {
i++
}
// 2. 判断符号
if i < len(s) && (s[i] == '+' || s[i] == '-') {
if s[i] == '-' {
sign = -1
}
i++
}
// 3. 逐位读取数字,处理溢出
for i < len(s) && s[i] >= '0' && s[i] <= '9' {
res = res*10 + int(s[i]-'0')
i++
if res > (1<<31)-1 {
if sign == 1 {
return (1 << 31) - 1
}
return -(1 << 31)
}
}
return res * sign
}
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 7. 整数反转 | 中等 | 数字溢出处理 |
| 65. 有效数字 | 困难 | 字符串解析状态机 |
| 415. 字符串相加 | 简单 | 字符串数字处理 |
| 43. 字符串相乘 | 中等 | 字符串数字模拟计算 |
| 165. 比较版本号 | 中等 | 字符串分段解析 |
| 12. 整数转罗马数字 | 中等 | 数字与字符串互转 |
本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0
许可协议,转载请注明出处!
