leetbook_ioa/docs/LCR 192. 把字符串转换成整数 (atoi).md
根据题意,有以下四种字符需要考虑:
$$ res = 10 \times res + x \ x = ascii(c) - ascii('0') $$
{:align=center width=450}
数字越界处理:
题目要求返回的数值范围应在 $[-2^{31}, 2^{31} - 1]$ ,因此需要考虑数字越界问题。而由于题目指出
环境只能存储 32 位大小的有符号整数,因此判断数字越界时,要始终保持 $res$ 在 int 类型的取值范围内。
在每轮数字拼接前,判断 $res$ 在此轮拼接后是否超过 $2147483647$ ,若超过则加上符号位直接返回。 设数字拼接边界 $bndry = 2147483647 // 10 = 214748364$ ,则以下两种情况越界:
$$ \begin{cases} res > bndry & 情况一:执行拼接 10 \times res \geq 2147483650 越界 \ res = bndry, x > 7 & 情况二:拼接后是 2147483648 或 2147483649 越界 \ \end{cases} $$
{:align=center width=450}
解题的整体流程为:
<,,,,,,>
class Solution:
def myAtoi(self, str: str) -> int:
str = str.strip() # 删除首尾空格
if not str: return 0 # 字符串为空则直接返回
res, i, sign = 0, 1, 1
int_max, int_min, bndry = 2 ** 31 - 1, -2 ** 31, 2 ** 31 // 10
if str[0] == '-': sign = -1 # 保存负号
elif str[0] != '+': i = 0 # 若无符号位,则需从 i = 0 开始数字拼接
for c in str[i:]:
if not '0' <= c <= '9' : break # 遇到非数字的字符则跳出
if res > bndry or res == bndry and c > '7': return int_max if sign == 1 else int_min # 数字越界处理
res = 10 * res + ord(c) - ord('0') # 数字拼接
return sign * res
class Solution {
public int myAtoi(String str) {
char[] c = str.trim().toCharArray();
if(c.length == 0) return 0;
int res = 0, bndry = Integer.MAX_VALUE / 10;
int i = 1, sign = 1;
if(c[0] == '-') sign = -1;
else if(c[0] != '+') i = 0;
for(int j = i; j < c.length; j++) {
if(c[j] < '0' || c[j] > '9') break;
if(res > bndry || res == bndry && c[j] > '7') return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = res * 10 + (c[j] - '0');
}
return sign * res;
}
}
若不使用 trim() / strip() 删除首部空格,而采取遍历跳过空格的方式,则可以将空间优化至 $O(1)$ ,代码如下:
class Solution:
def myAtoi(self, str: str) -> int:
res, i, sign, length = 0, 0, 1, len(str)
int_max, int_min, bndry = 2 ** 31 - 1, -2 ** 31, 2 ** 31 // 10
if not str: return 0 # 空字符串,提前返回
while str[i] == ' ':
i += 1
if i == length: return 0 # 字符串全为空格,提前返回
if str[i] == '-': sign = -1
if str[i] in '+-': i += 1
for j in range(i, length):
if not '0' <= str[j] <= '9' : break
if res > bndry or res == bndry and str[j] > '7':
return int_max if sign == 1 else int_min
res = 10 * res + ord(str[j]) - ord('0')
return sign * res
class Solution {
public int myAtoi(String str) {
int res = 0, bndry = Integer.MAX_VALUE / 10;
int i = 0, sign = 1, length = str.length();
if(length == 0) return 0;
while(str.charAt(i) == ' ')
if(++i == length) return 0;
if(str.charAt(i) == '-') sign = -1;
if(str.charAt(i) == '-' || str.charAt(i) == '+') i++;
for(int j = i; j < length; j++) {
if(str.charAt(j) < '0' || str.charAt(j) > '9') break;
if(res > bndry || res == bndry && str.charAt(j) > '7')
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = res * 10 + (str.charAt(j) - '0');
}
return sign * res;
}
}
class Solution {
public:
int myAtoi(string str) {
int res = 0, bndry = INT_MAX / 10;
int i = 0, sign = 1, length = str.size();
if(length == 0) return 0;
while(str[i] == ' ')
if(++i == length) return 0;
if(str[i] == '-') sign = -1;
if(str[i] == '-' || str[i] == '+') i++;
for(int j = i; j < length; j++) {
if(str[j] < '0' || str[j] > '9') break;
if(res > bndry || res == bndry && str[j] > '7')
return sign == 1 ? INT_MAX : INT_MIN;
res = res * 10 + (str[j] - '0');
}
return sign * res;
}
};