题号:8
题目描述:
1. 读入字符串并丢弃无用的前导空格
2. 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
3. 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
4. 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
5. 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
分析题目描述:
1. 如果开头是空格,忽略开头所有空格 去除前导空格
2. 检测是否是负数,如果检测到-号,最终要转化为负数 不然就是正数 默认 前置符号判断。利用res为1或者是-1来控制
3. 如果下一个字符是非数字,就停止读,非数字不能放进去 非数字判断。数字的ASCLL码在48和57之间,包括48和57,利用charCodeAt()方法
4. 如果一个数字都没有,就返回0
5. 如果正数 超过 2^31-1 就固定为2^31-1 Math.pow(2,31) 是否溢出判断
6. 如果负数 小于 -2^31 就固定为 -2^31 - Math.pow(2,31)
7. 取出字符组合成整数
8. 注意,如果是中间常出现了空格,比如“43 33” 只能得到43
代码
时间复杂度O(n) while循环遍历的次数 空间复杂度O(1) 没有用到数组
var myAtoi = function (s) {
let n = s.length - 1
let res = 0
let index = 0
let sign = 1
let max = Math.pow(2, 31) - 1
let min = - Math.pow(2, 31)
// 1. 长度不为0
if (s.length === 0) {
return 0
}
// 2. 前导空格
while (s[index] === ' ') {
index++
}
// 3. 开头是正号
if (s[index] === '+') {
sign = 1
index++
} else if (s[index] === '-') {
sign = -1
index++
}
while (index <= n) {
// 4. 如果中间碰到空格 '43 '
if (s[index] === ' ') {
return res * sign
}
// 5. 非数字
if (!(s.charCodeAt(index) >= 48 && s.charCodeAt(index) <= 57)) {
return res * sign
}
// 6. 化为整数【单个整数】
let num = s[index] - '0'
// 7. 整数拼接
res = res * 10 + num
// 8. 溢出判断
if (res * sign > max) {
return max
} else if (res * sign < min) {
return min
}
// 9. 更新索引
index++
}
// 10. 返回最终的结果 记得×符号
return res * sign
}
测试用例
console.log(myAtoi("42"));
console.log(myAtoi('-123456abccba'));
console.log(myAtoi("4193 with words"));
console.log(myAtoi("-91283472332"));
记录: 今日是8/19,第二次做了一遍这个题目,还是会出错:
- 再进行符号判断时,没有写index++
- while循环没有写 index++导致死循环
- 非字符判断,逻辑写错了