微信公众号:路人zhang
扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: 算法 > 剑指offer > 剑指offer 67. 把字符串转成整数

题目描述

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

函数 myAtoi(string s) 的算法如下:

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

注意:

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

示例 1:

输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"42"(读入 "42")
           ^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。

示例 2:

输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
            ^
第 2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
             ^
第 3 步:"   -42"(读入 "42")
               ^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。

示例 3:

输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
             ^
解析得到整数 4193 。
由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。

提示:

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

题解

(模拟) O(n)

注意一个边界:当不考虑符号时,假设计算结果为 INT_MAX + 1,不能将其变为 INT_MAX,因为如果答案是负数的话,-(INT_MAX + 1) = INT_MIN 是合理的,那么 -INT_MAX 就是错误答案。

其余情况按照题目描述模拟即可

时间复杂度

O(n)

空间复杂度

O(1)

C++ 代码

class Solution {
public:
    int myAtoi(string s) {
        long long res = 0;
        int k = 0;
        while (k < s.size() && s[k] == ' ') k ++ ;
        if (k == s.size()) return 0; // 全是空字符

        bool is_minus = false;
        if (s[k] == '+') k ++ ;
        else if (s[k] == '-') k ++ , is_minus = true;

        for (int i = k; i < s.size(); i ++ ) {
            if (isdigit(s[i])) {
                res = res * 10 + s[i] - '0';
                if (res > INT_MAX + 1ll) res = INT_MAX + 1ll;
                if (res < INT_MIN) res = INT_MIN;
            } else {
                break;
            }
        }

        if (is_minus) res = -res;

        if (res > INT_MAX) res = INT_MAX;
        
        return res;
    }
};

Java 代码

class Solution {
    public int strToInt(String s) {
        long res = 0;
        int k = 0;
        while (k < s.length() && s.charAt(k) == ' ') k ++ ;
        if (k == s.length()) return 0; // 全是空字符

        boolean isMinus = false;
        if (s.charAt(k) == '+') k ++ ;
        else if (s.charAt(k) == '-') {
            k ++ ;
            isMinus = true;
        }

        for (int i = k; i < s.length(); i ++ ) {
            if (Character.isDigit(s.charAt(i))) {
                res = res * 10 + (s.charAt(i) - '0');
                if (res > Integer.MAX_VALUE + 1L) res = Integer.MAX_VALUE + 1L;
                if (res < Integer.MIN_VALUE) res = Integer.MIN_VALUE;
            } else {
                break;
            }
        }

        if (isMinus) res = -res;

        if (res > Integer.MAX_VALUE) res = Integer.MAX_VALUE;

        return (int) res;
    }
}

Python 代码

class Solution:
    def strToInt(self, s: str) -> int:
        res = 0
        k = 0
        INT_MAX = 2**31 - 1
        INT_MIN = -2**31

        while k < len(s) and s[k] == ' ':
            k += 1
        if k == len(s):
            return 0  # 全是空字符

        isMinus = False
        if s[k] == '+':
            k += 1
        elif s[k] == '-':
            k += 1
            isMinus = True

        for i in range(k, len(s)):
            if s[i].isdigit():
                res = res * 10 + int(s[i])
                if not isMinus and res > INT_MAX:
                    res = INT_MAX
                    break
                if isMinus and res > INT_MAX + 1:
                    res = INT_MAX + 1
                    break
            else:
                break

        if isMinus:
            res = -res

        if res < INT_MIN:
            res = INT_MIN

        return res

本文由读者提供Github地址:https://github.com/tonngw


点击面试手册,获取本站面试手册PDF完整版