题目地址:

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

给定一个字符串 s s s,实现atoi函数。如果得数大于了 2 31 − 1 2^{31}−1 2311则返回 2 31 − 1 2^{31} − 1 2311,如果得数小于了 − 2 31 -2^{31} 231则返回 − 2 31 -2^{31} 231

先略过空格,再判断正负,然后开始parse字符串。在不使用long long的前提下,我们需要判断溢出。假设当前得到的数是 n n n(不考虑符号,即 n ≥ 0 n\ge 0 n0),当前看到的字符的数是 x x x,那么当 10 n + x > 2 31 − 1 10n+x>2^{31}-1 10n+x>2311的时候发生正溢出,这个等价于 n > ⌊ 2 31 − 1 − x 10 ⌋ n>\lfloor \frac{2^{31}-1-x}{10}\rfloor n>102311x;当 − 10 n − x < − 2 31 -10n-x<-2^{31} 10nx<231的时候发生负溢出,等价于 − n < ⌊ − 2 31 + x 10 ⌋ -n<\lfloor \frac{-2^{31}+x}{10} \rfloor n<10231+x。另外还需要注意一点,当 n n n被parse成 2 31 2^{31} 231的时候也会发生溢出,因为int的范围正数比负数少 1 1 1个数,所以如果在没发生溢出的情况下,出现了 n n n变成 2 31 2^{31} 231的情况,也需要返回 − 2 31 -2^{31} 231。代码如下:

class Solution {
 public:
  int myAtoi(string s) {
    int k = 0;
    while (k < s.size() && s[k] == ' ') k++;
    if (k == s.size()) return 0;

    int sign = 1;
    if (s[k] == '-') sign = -1, k++;
    else if (s[k] == '+') k++;

    int res = 0;
    for ( ; k < s.size() && '0' <= s[k] && s[k] <= '9'; k++) {
      int x = s[k] - '0';
      if (sign == 1 && res > (INT_MAX - x) / 10) return INT_MAX;
      if (sign == -1 && -res < (INT_MIN + x) / 10) return INT_MIN;
      if (-res * 10 - x == INT_MIN) return INT_MIN;
      res = res * 10 + x;
    }
    return sign * res;
  }
};

时间复杂度 O ( l s ) O(l_s) O(ls),空间 O ( 1 ) O(1) O(1)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐