LeetCode 第8题:字符串转换整数 (atoi)

LeetCode 第8题:字符串转换整数 (atoi)

题目描述

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。

函数 myAtoi(string s) 的算法需要按照以下步骤:

  1. 读入字符串并丢弃无用的前导空格
  2. 检查下一个字符是否为正负号,读取该字符(如果有)
  3. 读取数字字符,直到遇到非数字字符或到达字符串末尾
  4. 将前面读入的字符转换为整数,如果没有读入数字,则值为0
  5. 如果整数超过32位有符号整数范围 [−2³¹, 2³¹ − 1],需要截断这个整数

难度

中等

题目链接

https://leetcode.cn/problems/string-to-integer-atoi/

示例

示例 1:

输入:s = "42"
输出:42
解释:
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
第 3 步:"42"(读入 "42"

示例 2:

输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
第 2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
第 3 步:"   -42"(读入 "42"

示例 3:

输入:s = "4193 with words"
输出:4193
解释:转换截止于数字 '3' ,因为它的下一个字符不为数字

提示

  • 0 <= s.length <= 200
  • s 由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成

解题思路

方法:模拟法

这道题的关键是按照题目要求,严格模拟字符串转换整数的过程。需要注意以下几点:

  1. 状态机思想:

    • 处理空格状态
    • 处理符号状态
    • 处理数字状态
    • 处理结束状态
  2. 边界处理:

    • 整数范围检查
    • 符号处理
    • 非法字符处理
  3. 溢出处理:

    • 在加入新的数字前检查是否会溢出
    • 使用long类型暂存结果

时间复杂度:O(n),其中n是字符串长度
空间复杂度:O(1)

代码实现

C# 实现

public class Solution {
    public int MyAtoi(string s) {
        int i = 0;
        int n = s.Length;
      
        // 1. 跳过前导空格
        while (i < n && s[i] == ' ') {
            i++;
        }
      
        // 2. 处理符号
        int sign = 1;
        if (i < n && (s[i] == '+' || s[i] == '-')) {
            sign = s[i] == '+' ? 1 : -1;
            i++;
        }
      
        // 3. 转换数字
        long result = 0;
        while (i < n && char.IsDigit(s[i])) {
            result = result * 10 + (s[i] - '0');
          
            // 4. 处理溢出
            if (sign == 1 && result > int.MaxValue) {
                return int.MaxValue;
            }
            if (sign == -1 && -result < int.MinValue) {
                return int.MinValue;
            }
          
            i++;
        }
      
        return (int)(sign * result);
    }
}

优化版本(使用状态机)

public class Solution {
    private enum State { Start, Signed, Number, End }
  
    public int MyAtoi(string s) {
        State state = State.Start;
        int sign = 1;
        long result = 0;
      
        foreach (char c in s) {
            if (state == State.End) {
                break;
            }
          
            switch (state) {
                case State.Start:
                    if (c == ' ') continue;
                    if (c == '+' || c == '-') {
                        sign = c == '+' ? 1 : -1;
                        state = State.Signed;
                    }
                    else if (char.IsDigit(c)) {
                        result = c - '0';
                        state = State.Number;
                    }
                    else {
                        state = State.End;
                    }
                    break;
                  
                case State.Signed:
                    if (char.IsDigit(c)) {
                        result = c - '0';
                        state = State.Number;
                    }
                    else {
                        state = State.End;
                    }
                    break;
                  
                case State.Number:
                    if (char.IsDigit(c)) {
                        result = result * 10 + (c - '0');
                        if (sign == 1 && result > int.MaxValue) {
                            return int.MaxValue;
                        }
                        if (sign == -1 && -result < int.MinValue) {
                            return int.MinValue;
                        }
                    }
                    else {
                        state = State.End;
                    }
                    break;
            }
        }
      
        return (int)(sign * result);
    }
}

代码详解

  1. 基础版本:

    • 按步骤处理:空格、符号、数字
    • 使用long类型避免溢出
    • 及时检查边界条件
  2. 状态机版本:

    • 使用枚举定义状态
    • 更清晰的状态转换
    • 更好的可维护性和可扩展性

执行结果

基础版本:

  • 执行用时:72 ms
  • 内存消耗:38.4 MB

状态机版本:

  • 执行用时:68 ms
  • 内存消耗:38.2 MB

总结与反思

  1. 这是一道考察细节处理的题目:

    • 需要严格按照规则处理
    • 边界条件很多
    • 状态转换需要清晰
  2. 关键点:

    • 溢出处理
    • 状态转换
    • 异常处理
  3. 优化思路:

    • 使用状态机使逻辑更清晰
    • 提前处理特殊情况
    • 减少不必要的计算

相关题目

posted @   旧厂街小江  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示