分析
-
本题的考点:数学。
-
首先需要过滤掉前面的空格,然后判断数字的正负,记录在
minus
中,初始令res = 0
,然后读入后面的数据,遇到不是0~9
的字符结束循环,最终将res乘以minus
返回即可。 -
还要注意
res
可能越界的问题(此时res
中还没有考虑符号,即res>0
),分为两种情况:
(1)假设int
的最大值为INT_MAX
,则当minus>0
,说明结果为正数,若$res \times 10 + x > INT\_MAX$,即$res > \frac{INT\_MAX - x}{10}$的话越界,返回0;
(2)假设int
的最小值为INT_MIN
,则当minus<0
,说明结果为负数,若$-res \times 10 - x < INT\_MIN$,即$-res < \frac{INT\_MIN + x}{10}$的话越界,返回0;
- 另外还有一种边界情况,因为
int
的范围是[-2147483638, 2147483647]
,当结果为-2147483638
时,我们的程序因为此时没有考虑符号,此时res = 2147483638
,超过int
最大值,会越界,此时会正好变为-2147483638
,其实这样来说其实也没有问题,但是在LeetCode
的C++
中需要特判一下,否则无法提交通过。
代码
- C++
class Solution {
public:
int myAtoi(string s) {
int k = 0;
while (k < s.size() && s[k] == ' ') k++; // 过滤掉开始的空格
if (k == s.size()) return 0;
int minus = 1; // 表示是整数还是负数
if (s[k] == '-') minus = -1, k++;
else if (s[k] == '+') k++;
int res = 0;
while (k < s.size() && s[k] >= '0' && s[k] <= '9') {
int x = s[k] - '0';
// 考虑边界
if (minus > 0 && res > (INT_MAX - x) / 10) return INT_MAX;
if (minus < 0 && -res < (INT_MIN + x) / 10) return INT_MIN;
if (-res * 10 - x == INT_MIN) return INT_MIN; // 本地调试不用加这句话也是正确的
res = res * 10 + x;
k++;
}
return res * minus;
}
};
- Java
class Solution {
public int myAtoi(String s) {
char[] cs = s.toCharArray();
int k = 0;
while (k < cs.length && cs[k] == ' ') k++;
if (k == cs.length) return 0;
int minus = 1;
if (cs[k] == '-') {
minus = -1; k++;
} else if (cs[k] == '+') k++;
int res = 0;
while (k < cs.length && cs[k] >= '0' && cs[k] <= '9') {
int x = cs[k] - '0';
// 考虑边界
if (minus > 0 && res > (Integer.MAX_VALUE - x) / 10) return Integer.MAX_VALUE;
if (minus < 0 && -res < (Integer.MIN_VALUE + x) / 10) return Integer.MIN_VALUE;
// Java不用考虑这种情况
res = res * 10 + x;
k++;
}
return res * minus;
}
}
时空复杂度分析
-
时间复杂度:$O(n)$,
n
为的字符串的长度。 -
空间复杂度:$O(1)$。