解题思路
本题第一反应就是顺序遍历字符串的每一个字符,然后根据题目要求进行判断,显然本题的难点就不在于算法本身,而在于对于各种情况和边界的考虑:
(1)如何去除开头空格字符;
- 可以通过顺序遍历字符串字符,判断是否为空字符,如果是跳过该字符到下一个字符,直到第一个非空字符即可
(2)如何定位并标记符号位字符;
- 定义一个变量
flag
,第一个非空字符为'+'
标记为1
,为'-'
标记为-1
(3)如何截取连续数字字符;
- 通过顺序遍历,判断是否为数字字符
'0'-'9'
(4)如何将连续数字字符串转为整数;
该数字字符-'0'
就是该数字字符对应的数值,例如:'7'-'0'=7
;- 那如果是一串连续的数字字符组成的字符串呢,如:
"123"
,此时,没法用上面的方法直接得到,可以如下: - 设置一个
base=0
,顺序遍历“123”
: - 当遍历到
'1'
时,base = base * 10 + '1' - '0'
,得到base = 1
- 当遍历到
'2'
时,base = base * 10 + '2' - '0' = 1 * 10 + 2
,得到base = 12
- 当遍历到
'3'
时,base = base * 10 + '3' - '0' = 12 * 10 + 33
,得到base = 123
- 遍历结束,得到结果为:123
- 然后再根据符号位标记,得到最终结果,与符号位相乘
(5)如何判断越界;
- 数值范围为 [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [−231,231−1]。如果数值超过这个范围,返回 I N T _ M A X ( 2 31 − 1 ) INT\_MAX (2^{31} − 1) INT_MAX(231−1) 或 I N T _ M I N ( − 2 31 ) INT\_MIN (−2^{31}) INT_MIN(−231)
- 实现时用
Integer.valueOf()
函数抛出的异常来判断整数越界
(6)如何考虑程序的完整性;
- 第一个非空字符既不是正号或负号,也不是数字,返回0;
- 字符串为空,或者字符串内只包含空字符,返回0;
- 第一个非空字符是正号或负号,但接下来的第二个字符不是数字,返回0;
对于"+-2"、"+ 2"这两种情况,都返回0
Java
代码
class Solution {
public int myAtoi(String str) {
//如果字符串为null或长度小于1,返回0
if(str == null || str.length() < 1) return 0;
int idx = 0; //索引
//去除开头空格
while(idx < str.length() && str.charAt(idx) == ' '){
idx++;
}
int flag = 1; //标记正负
int base = 0; //数值
//标记符号位
if(idx < str.length() && (str.charAt(idx) == '+' || str.charAt(idx) == '-')){
flag = (str.charAt(idx) == '+') ? 1 : -1;
idx++;
}
//截取数值及越界判断
while(idx < str.length() && str.charAt(idx) >= '0' && str.charAt(idx) <= '9'){
//Integer.MAX_VALUE=2147483647
//Integer.MIN_VALUE=-2147483648
//越界判断
//base > Integer.MAX_VALUE / 10时,base * 10 就会越界
//base == Integer.MAX_VALUE / 10 = 214748364,base * 10 = 2147483640,最后一个数就不能大于7
if (base > Integer.MAX_VALUE / 10 || (base == Integer.MAX_VALUE / 10 && str.charAt(idx) - '0' > 7)) {
return (flag == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
// 计算转换值
base = 10 * base + (str.charAt(idx++) - '0');
}
return base * flag;
}
}
Python3
代码
class Solution:
def myAtoi(self, str: str) -> int:
str = str.lstrip() # 去除开头的空格
if str == '': # 为空
return 0
idx = 0
flag = 1
ret = '0'
if idx < len(str) and (str[idx] == '+' or str[idx] == '-'):
flag = 1 if (str[idx] == '+') else -1
idx += 1
while(idx < len(str) and str[idx].isdigit()):
ret += str[idx]
idx += 1
result = int(ret) * flag
if result > 2147483647:
return 2147483647
elif result < -2147483648:
return -2147483648
else:
return result
C++
代码
class Solution {
public:
int myAtoi(string str) {
int i = 0;
while(' ' == str[i]) i++;// 去掉空格
int flag = 1;
if(i < str.size() && (str[i] == '+' || str[i] == '-')){
flag = (str[i] == '+') ? 1 : -1;
i++;
}
int base = 0;
while(i < str.size() && str[i] >= '0' && str[i] <= '9'){
if ((base > INT_MAX / 10) || (base == INT_MAX / 10 && (str[i] - '0') > 7)) {
return (flag == 1) ? INT_MAX : INT_MIN;
}
base = base * 10 + (str[i] - '0');
i++;
}
return base * flag;
}
};