题目描述
实现 myAtoi(string s)
函数,将字符串转换成 32 位有符号整数。函数首先丢弃字符串前面的空格字符,直到找到第一个非空格字符为止。然后,选择该非空格字符和之后的连续字符组成一个存储整数的字符串。字符串可以包含额外字符,这些字符在形成整数的字符串后面,并被忽略。如果第一个非空格字符不是数字且不是符号+
或者-
,则不进行转换并返回 0。如果转换过程中存在任何无法识别的字符,则提前停止转换,并返回已经得到的结果。如果转换后的结果超过 32 位有符号整数范围 [−2^31, 2^31 − 1]
,则返回整数边界。
实现思路
- 忽略字符串前导空格。
- 检查是否有正负号,并初始化结果变量。
- 从第一个非空字符开始,逐个检查是否为数字。
- 如果遇到非数字字符,停止处理。
- 将数字字符转换为整数并累加到结果中。
- 检查结果是否溢出,并在必要时修正结果。
- 返回最终结果。
算法实现
C
int myAtoi(char *str) {
long res = 0;
int i = 0, sign = 1;
while (str[i] == ' ') i++; // 忽略前导空格
if (str[i] == '-' || str[i] == '+') { // 处理正负号
sign = (str[i++] == '-') ? -1 : 1;
}
while (str[i]) {
if (str[i] >= '0' && str[i] <= '9') {
res = res * 10 + (str[i++] - '0');
if (res > INT_MAX) return (sign == -1) ? INT_MIN : INT_MAX; // 检查溢出
} else break; // 非数字字符,停止处理
}
return res * sign; // 应用正负号
}
Python
def myAtoi(s: str) -> int:
import re
s = s.lstrip()
if not s: return 0
match = re.match(r"^[+-]?(\d+)", s)
if not match: return 0
result = int(match.group(0))
return max(min(result, 2**31 - 1), -2**31)
Java
public int myAtoi(String s) {
long result = 0;
int sign = 1;
int index = 0;
int n = s.length();
// 忽略前导空格
while (index < n && s.charAt(index) == ' ') index++;
// 处理正负号
if (index < n && (s.charAt(index) == '+' || s.charAt(index) == '-')) {
sign = s.charAt(index++) == '+' ? 1 : -1;
}
// 转换数字并检查溢出
while (index < n && Character.isDigit(s.charAt(index))) {
int digit = s.charAt(index++) - '0';
if (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && digit > 7)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
result = 10 * result + digit;
}
return (int) (sign * result);
}
时间复杂度
时间复杂度为 O(n),其中 n 是字符串的长度。这是因为算法需要遍历整个字符串来查找数字并计算结果。空间复杂度为 O(1),因为使用的额外空间不依赖于输入字符串的大小。