String to Integer (atoi)(字符串转换整数)
题目 / Problem
中文: 实现 myAtoi(s),将字符串 s 转换为一个 32 位有符号整数。
转换过程如下:
- 忽略字符串开头的空格
' '。 - 如果下一个字符是
'+'或'-',读取符号;否则默认为正数。 - 连续读取数字字符,直到遇到第一个非数字字符或到达字符串末尾。前导零不会影响结果。
- 如果没有读取到任何数字,返回
0。 - 如果结果超出 32 位有符号整数范围
[-2^31, 2^31 - 1],将其限制在该范围内。
English: Implement myAtoi(s), which converts a string s to a 32-bit signed integer.
The conversion follows these rules:
- Ignore leading space characters
' '. - Read an optional
'+'or'-'sign; assume positive if neither is present. - Read consecutive digits until the first non-digit character or the end of the string. Leading zeros do not affect the result.
- Return
0if no digits are read. - Clamp values outside the 32-bit signed integer range
[-2^31, 2^31 - 1].
32 位整数范围 / 32-bit Integer Range
INT_MIN = -2^31 = -2147483648
INT_MAX = 2^31 - 1 = 2147483647
正数和负数的绝对值上限不同:负数可以达到 2147483648,而正数最大只能达到 2147483647。
The positive and negative magnitude limits differ: a negative number may have magnitude 2147483648, while a positive number is limited to 2147483647.
示例 / Examples
Example 1
Input: s = "42"
Output: 42
没有前导空格和符号,直接读取连续数字 "42"。
There is no leading space or sign, so the consecutive digits "42" are read directly.
Example 2
Input: s = " -042"
Output: -42
跳过前导空格,读取负号,然后读取 "042"。
Skip the leading spaces, read the negative sign, and then read "042".
Example 3
Input: s = "1337c0d3"
Output: 1337
读取 "1337" 后遇到非数字字符 'c',转换立即停止,后面的内容不再处理。
After reading "1337", conversion stops at the non-digit 'c'; the remaining characters are ignored.
Example 4
Input: s = "0-1"
Output: 0
读取数字 '0' 后遇到 '-',因此停止。符号只允许出现在数字序列之前。
Reading stops at '-' after the digit '0'. A sign is only valid before the digit sequence.
Example 5
Input: s = "words and 987"
Output: 0
第一个有效位置是非数字字符 'w',没有读取到数字,所以返回 0。
The first relevant character is the non-digit 'w'. Since no digits are read, return 0.
约束 / Constraints
0 <= s.length <= 200s由英文字母、数字0-9、空格' '、'+'、'-'和'.'组成。sconsists of English letters, digits0-9, space' ','+','-', and'.'.
解题思路:顺序模拟 / Approach: Sequential Simulation
使用指针 index 从左到右处理字符串,严格按照题目规定的阶段执行:
Use a pointer index to process the string from left to right in the required order:
跳过前导空格
Skip leading spaces
↓
读取一次可选符号
Read one optional sign
↓
读取连续数字
Read consecutive digits
↓
遇到非数字后停止
Stop at the first non-digit
↓
应用符号并返回
Apply the sign and return
阶段顺序不能重复。例如,读取数字以后遇到空格或符号,都必须停止,不能再次跳过或解析。
These phases cannot restart. For example, a space or sign encountered after digit parsing begins must stop the conversion.
数字累积 / Building the Number
读取一个数字字符时,将字符转成数字 digit,并更新:
For each digit character, convert it to digit and update:
value = value * 10 + digit;
可以通过字符编码完成数字转换:
The digit can be obtained using character codes:
const digit = s.charCodeAt(index) - 48;
其中字符 '0' 的编码是 48。
The character code of '0' is 48.
溢出检查 / Overflow Check
不要等到构造出一个极大的数字后才截断。加入新数字 digit 之前,先检查:
Do not wait until an extremely large number has been built. Before appending digit, check:
value * 10 + digit > limit
为避免先执行乘法,可以将条件变形为:
To avoid performing the multiplication first, rearrange it as:
value > floor((limit - digit) / 10)
其中:
Where:
正数 / Positive: limit = 2147483647
负数 / Negative: limit = 2147483648
一旦检测到溢出,就可以立即返回对应边界值。
Once overflow is detected, return the corresponding boundary immediately.
JavaScript 实现 / JavaScript Implementation
/**
* @param {string} s
* @return {number}
*/
function myAtoi(s) {
const INT_MAX = 2 ** 31 - 1;
const INT_MIN = -(2 ** 31);
let index = 0;
let sign = 1;
let value = 0;
// 1. 跳过前导空格 / Skip leading spaces
while (index < s.length && s[index] === " ") {
index++;
}
// 2. 读取可选符号 / Read an optional sign
if (index < s.length && (s[index] === "+" || s[index] === "-")) {
sign = s[index] === "-" ? -1 : 1;
index++;
}
// 负数允许的绝对值比正数多 1
// The negative magnitude limit is one larger
const limit = sign === 1 ? INT_MAX : 2 ** 31;
// 3. 读取连续数字 / Read consecutive digits
while (index < s.length) {
const charCode = s.charCodeAt(index);
if (charCode < 48 || charCode > 57) {
break;
}
const digit = charCode - 48;
// 在执行 value * 10 + digit 前检查溢出
// Check overflow before value * 10 + digit
if (value > Math.floor((limit - digit) / 10)) {
return sign === 1 ? INT_MAX : INT_MIN;
}
value = value * 10 + digit;
index++;
}
return sign * value;
}
执行过程 / Walkthrough
以 s = " -042abc" 为例:
For s = " -042abc":
| 阶段 / Stage | 读取内容 / Input read | 状态 / State |
|---|---|---|
| 跳过空格 / Skip spaces | " " | index = 3 |
| 读取符号 / Read sign | '-' | sign = -1 |
| 读取数字 / Read digit | '0' | value = 0 |
| 读取数字 / Read digit | '4' | value = 4 |
| 读取数字 / Read digit | '2' | value = 42 |
| 遇到非数字 / Non-digit | 'a' | 停止 / Stop |
最终返回:
Finally return:
sign × value = -1 × 42 = -42
边界情况 / Edge Cases
空字符串或只有空格 / Empty or Spaces Only
"" → 0
" " → 0
只有符号 / Sign Only
"+" → 0
"-" → 0
读取符号后没有数字,value 仍为 0。
If no digit follows the sign, value remains 0.
多个符号 / Multiple Signs
"+-12" → 0
"--12" → 0
只允许读取一个可选符号;第二个符号不是数字,因此转换停止。
Only one optional sign may be read. The second sign is not a digit, so conversion stops.
超出范围 / Out of Range
"2147483648" → 2147483647
"-2147483649" → -2147483648
复杂度 / Complexity
设 n = s.length。
Let n = s.length.
- 时间复杂度 / Time:
O(n),每个相关字符最多读取一次。
Each relevant character is examined at most once. - 空间复杂度 / Space:
O(1),只使用常数个变量。
Only a constant number of variables is used.
易错点 / Common Pitfalls
- 只能忽略开头的普通空格
' ',数字读取开始后不能继续跳过空格。
Ignore only leading space characters' '; do not skip spaces after parsing starts. - 符号最多读取一次,并且必须出现在数字序列之前。
Read at most one sign, and only before the digit sequence. - 遇到第一个非数字字符后必须立即停止,不能跳过它继续寻找后面的数字。
Stop at the first non-digit instead of skipping it to search for later digits. - 正数上限为
2147483647,负数绝对值上限为2147483648。
The positive limit is2147483647, while the negative magnitude limit is2147483648. - 不能直接使用
parseInt()代替题目要求的解析过程,否则无法体现并控制所有规则和溢出处理。
Do not replace the required parsing logic withparseInt(); implement and control every rule explicitly.