一、原题
请你来实现一个 myAtoi(string s)
函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi
函数)。
函数 myAtoi(string s)
的算法如下:
- 读入字符串并丢弃无用的前导空格
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为
0
。必要时更改符号(从步骤 2 开始)。 - 如果整数数超过 32 位有符号整数范围
,需要截断这个整数,使其保持在这个范围内。具体来说,小于
的整数应该被固定为
,大于
的整数应该被固定为
。
- 返回整数作为最终结果。
注意:
- 本题中的空白字符只包括空格字符 ' ' 。
- 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
示例 1:
输入:s = "42" 输出:42 解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。 第 1 步:"42"(当前没有读入字符,因为没有前导空格) ^ 第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+') ^ 第 3 步:"42"(读入 "42") ^ 解析得到整数 42 。 由于 "42" 在范围 内,最终结果为 42 。
示例 2:
输入:s = " -42" 输出:-42 解释: 第 1 步:" -42"(读入前导空格,但忽视掉) ^ 第 2 步:" -42"(读入 '-' 字符,所以结果应该是负数) ^ 第 3 步:" -42"(读入 "42") ^ 解析得到整数 -42 。 由于 "-42" 在范围 内,最终结果为 -42 。
示例 3:
输入:s = "4193 with words" 输出:4193 解释: 第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格) ^ 第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+') ^ 第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止) ^ 解析得到整数 4193 。 由于 "4193" 在范围内,最终结果为 4193 。
二、心得
五一长假后的第一天从fighting开始~
题中给出的函数 myAtoi(string s) 的算法已经很清晰明了了,只需要一步一步来就OK啦。最贴合算法的测试用例无非就是类似于 s = " -123456" 这样的例子,个别用例会删除或改动位置,如 s = "0-1245", s = "words and 987"等。但都不影响代码的正确执行顺序,即:
①判断是否有空格符号;②判断是否有正负号;③判断是否为数字字符 |
今日手感好,直接上结果:
class Solution {
public int myAtoi(String s) {
if(s.length() == 0){
return 0;
}
int index = 0, n = s.length(), sign = 1, res = 0;
// 处理前置空格
while(index < n && s.charAt(index) == ' '){
index ++;
}
// 处理正负号
if(index < n && (s.charAt(index) == '+' || s.charAt(index) == '-')){
sign = s.charAt(index) == '+' ? 1 : -1;
index ++;
}
// 处理数字
while(index < n && Character.isDigit(s.charAt(index))){
int digit = s.charAt(index) - '0';
if(res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && digit > 7)){
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
res = res * 10 + digit;
index ++;
}
return res * sign;
}
}
首先先判空,初始化变量:
index | 索引,指向 s 中序号为 index 的字符 |
n | s 的总长度 |
sign | 若 sign = 1,表明符号为正号;若 sign = -1,表明符号为负号 |
res | 返回值,类型为整数类型 |
整体框架就是上述顺序的三步骤,一旦找到符合情况的字符,执行依次后都需要将 index 加一(我吃了这个亏,┭┮﹏┭┮)。
着重解释一下处理数字部分的代码:该部分只考虑数字部分,不考虑正负号部分,即不考虑是正数还是负数。这里使用了 Character.isDigit(s.charAt(index)) ,判断序号为 index 的字符是否是 0~9,如果是则返回 true,反之则返回 false。至于为什么要使用 s.charAt(index) - '0' 转整数类型,原因是在Java中,字符 '0' 到 '9' 的ASCII码值是连续的,依次为 48 到 57,当我们需要将一个字符表示的数字转换为整数时,可以通过减去字符 '0' 的ASCII码值来得到对应的整数值。之后的代码跟上一篇我写的文章一样的道理,有执行顺序的。
最后返回 res * sign ,若 sign = 1,则返回值为正数,若 sign = -1,则返回值为负数。
啊哈?执行时间击败100%使用Java的用户,这可能吗,(・∀・(・∀・(・∀・*)~