LeetCode 8. 字符串转换整数 (atoi)

题目描述

8. 字符串转换整数 (atoi)

image-20250419022104874

思路分析

解法一:模拟(推荐)

核心思路

按照题目描述逐步处理字符串,关键是正确处理 4 个步骤的顺序和溢出判断:

  1. 跳过前导空格while s[i] == ' '
  2. 判断符号位'+''-',默认为正
  3. 逐位读取数字while s[i] in ['0'..'9']res = res * 10 + digit
  4. 溢出处理:数字超过 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. 整数转罗马数字 中等 数字与字符串互转
本文作者:
本文链接: https://hgnulb.github.io/blog/2025/71927843
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!