Leetcode算法题:字符串转换整数(atoi)
题解:实现 atoi 函数
 
题目描述:
实现一个 atoi 函数,能够将字符串转换为一个整数。该函数会忽略前导空格,并处理可选的符号(+ 或 -),直到遇到非数字字符为止。若字符串中的数字超出了 32 位带符号整数的范围,返回 Integer.MAX_VALUE 或 Integer.MIN_VALUE。
题目要求:
-  只允许处理数字,符号( +或-)以及空格字符。
-  返回转换后的整数值。若遇到溢出情况,返回 Integer.MAX_VALUE或Integer.MIN_VALUE。
-  对于无效输入(如字符串中没有数字),返回 0。 
解题思路:
-  去除前导空格: -  根据题目要求,输入字符串可能包含前导空格。我们需要去除这些空格,直到遇到第一个有效字符(数字或符号)。 
-  通过一个 while循环逐步遍历字符,直到找到第一个非空格字符,更新字符串的起始位置。
 
-  
-  处理符号位: -  在去除空格后,可能会遇到一个符号字符( +或-)。如果遇到-,我们需要记住这个符号,之后将转换后的结果乘以 -1。如果遇到+,则继续处理下一个字符。
-  注意:这里不能使用 for循环,因为我们不应该扫描整个字符串中的每一个符号,应该只在符号字符后处理一次符号。
 
-  
-  解析数字: -  在处理完符号后,接下来解析字符串中的数字部分。遍历字符直到遇到非数字字符(如字母、空格等)。 
-  每遇到一个数字字符,就将其转换为对应的整数值(通过 charAt(i) - '0')。然后将之前的数字结果乘以 10 并加上当前的数字。
 
-  
-  溢出检查: -  在数字解析过程中,需要时刻检查是否会发生溢出。具体来说,如果当前 num已经大于Integer.MAX_VALUE / 10,那么再乘以 10 就会溢出。如果num等于Integer.MAX_VALUE / 10,那么还需要进一步检查当前数字是否大于Integer.MAX_VALUE % 10,以确定是否溢出。
-  若发生溢出,应该返回 Integer.MAX_VALUE或Integer.MIN_VALUE,具体取决于符号。
 
-  
-  返回结果: -  将解析出的数字乘上符号( mark)后返回结果。
 
-  
代码实现:
class Solution {public int myAtoi(String s) {int mark = 1; // 标记符号,默认为正数int num = 0;  // 存储转换后的数字int i = 0;    // 遍历字符串的指针// 1. 去除前导空格while (i < s.length() && s.charAt(i) == ' ') {i++;}// 2. 如果字符串为空或仅包含空格,返回 0if (i == s.length()) {return 0;}// 3. 处理符号位if (s.charAt(i) == '-') {mark = -1;i++;} else if (s.charAt(i) == '+') {i++;}// 4. 解析数字部分while (i < s.length() && Character.isDigit(s.charAt(i))) {int digit = s.charAt(i) - '0';// 5. 检查是否发生溢出if (num > Integer.MAX_VALUE / 10 || (num == Integer.MAX_VALUE / 10 && digit > Integer.MAX_VALUE % 10)) {return mark == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;}// 更新数字num = num * 10 + digit;i++;}// 6. 返回最终结果return num * mark;}
}
代码分析:
-  去除前导空格: -  使用 while循环检查字符串中的每个字符,直到遇到第一个非空格字符。这样,我们可以确保从有效字符开始解析。
 
-  
-  处理符号位: -  如果遇到 -,我们将mark设置为 -1,表示结果为负数。如果是+,则继续处理。
-  对符号的处理只需要一次,因此我们在符号后直接跳过。 
 
-  
-  解析数字: -  每次遇到数字字符时,通过 charAt(i) - '0'将字符转换为对应的数字,并累积到num变量中。这样就实现了逐位构建整数的功能。
 
-  
-  溢出检查: -  在每次更新 num时,我们先检查是否会发生溢出。如果会溢出,直接返回Integer.MAX_VALUE或Integer.MIN_VALUE。
 
-  
-  最终结果: -  处理完所有字符后,返回结果 num,并根据符号进行调整。
 
-  
时间复杂度:
-  时间复杂度:O(n),其中 n是字符串s的长度。我们只遍历字符串一次,处理每个字符的时间是常数级别的。
-  空间复杂度:O(1),我们只用了少量的额外空间来存储标记符号、数字结果和遍历指针。 
边界情况:
-  输入为空或只有空格时,返回 0。 
-  输入包含符号 +或-时,正确解析符号。
-  输入中包含非数字字符时,忽略这些字符,只解析数字部分。 
-  超过整数范围时,返回 Integer.MAX_VALUE或Integer.MIN_VALUE。
总结:
-  本题的关键是如何正确地处理前导空格、符号、数字部分的解析以及溢出检测。 
-  通过分步实现每个功能,我们确保了代码的清晰和准确性,同时也考虑了所有可能的边界情况,如溢出、无效字符等。 
