侧边栏壁纸
  • 累计撰写 416 篇文章
  • 累计创建 65 个标签
  • 累计收到 150 条评论

目 录CONTENT

文章目录

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

Z同学
2022-05-03 / 0 评论 / 1 点赞 / 3,777 阅读 / 1,099 字
温馨提示:
本文最后更新于 2022-10-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 题目

实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

该函数的算法要求如下:

  1. 读入字符串并丢弃无用的前导空格
  2. 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
  3. 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  4. 将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
  5. 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
  6. 返回整数作为最终结果。

注意:

本题中的空白字符只包括空格字符 ' '
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:

输入:s = "42"
输出:42


示例 2:
输入:s = "   -42"
输出:-42

示例 3:
输入:s = "4193 with words"
输出:4193

提示:

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

2. 解题

直接执行暴力破解

class Solution {
    public int myAtoi(String s) {
 		int sign = 1;
        int res = 0;
        int m = s.length();
        int i = 0;
        while(i < m && s.charAt(i)==' '){
            i++;
        }
        int start = i;
        for(; i < m; i++){
            char c = s.charAt(i);
            if(i==start && c=='+'){
                sign = 1;
            }else if(i==start && c=='-'){
                sign = -1;
            }else if(Character.isDigit(c)){ //判断char 是否属于整数,也就是0至9的值。 
                int num = c-'0';
                // 只能存储 32 位大小的有符号整数,因此,需要提前判:断乘以 10 以后是否越界
                if(res > Integer.MAX_VALUE/10 || (res == Integer.MAX_VALUE/10&&num>Integer.MAX_VALUE%10)){
                    return Integer.MAX_VALUE;
                }

                if(res < Integer.MIN_VALUE/10 || (res == Integer.MIN_VALUE/10&&-num<Integer.MIN_VALUE%10)){
                    return Integer.MIN_VALUE;
                }
                res = res*10+sign*num;
            }else{
                break;
            }
        }
        return res;
    }
}

执行用时: 1 ms

内存消耗: 41.1 MB

可以优化简单改改代码:

class Solution {
    public int myAtoi(String s) {
        s = s.trim();
        if (s.length() == 0) {
            return 0;
        }
        boolean isnegative = false;
        int res = 0;
        int i = 0;
        char c = s.charAt(i);
        if (c == '+') {
            i++;
        } else if (c == '-') {
            i++;
            isnegative = true;
        }
        for (; i < s.length(); i++) {
            c = s.charAt(i);
            if (Character.isDigit(c)) {
                int num = c - '0'; //将char 转int
                if (res > (Integer.MAX_VALUE - num) / 10) {
                    return isnegative ? Integer.MIN_VALUE : Integer.MAX_VALUE;
                }
                res = res * 10 + num;
            } else {
                break;
            }
        }
        return isnegative ? -res : res;

执行用时: 1 ms

内存消耗: 41.3 MB

整体的消耗都差不多,官方通过自动机实现的,效果如下:

class Solution {
    public int myAtoi(String str) {
        Automaton automaton = new Automaton();
        int length = str.length();
        for (int i = 0; i < length; ++i) {
            automaton.get(str.charAt(i));
        }
        return (int) (automaton.sign * automaton.ans);
    }
}

class Automaton {
    public int sign = 1;
    public long ans = 0;
    private String state = "start";
    private Map<String, String[]> table = new HashMap<String, String[]>() {{
        put("start", new String[]{"start", "signed", "in_number", "end"});
        put("signed", new String[]{"end", "end", "in_number", "end"});
        put("in_number", new String[]{"end", "end", "in_number", "end"});
        put("end", new String[]{"end", "end", "end", "end"});
    }};

    public void get(char c) {
        state = table.get(state)[get_col(c)];
        if ("in_number".equals(state)) {
            ans = ans * 10 + c - '0';
            ans = sign == 1 ? Math.min(ans, (long) Integer.MAX_VALUE) : Math.min(ans, -(long) Integer.MIN_VALUE);
        } else if ("signed".equals(state)) {
            sign = c == '+' ? 1 : -1;
        }
    }

    private int get_col(char c) {
        if (c == ' ') {
            return 0;
        }
        if (c == '+' || c == '-') {
            return 1;
        }
        if (Character.isDigit(c)) {
            return 2;
        }
        return 3;
    }
}

执行用时:2 ms

内存消耗:41.1 MB

两者之间,差距还是比较明显的。

参考链接
题目来源 链接:https://leetcode.cn/problems/string-to-integer-atoi

1

评论区