實作
myAtoi(s):把字串轉成 32 位元有號整數。規則:略過前導空白 → 可選正負號 → 讀取連續數字(遇非數字停止)→ 超出[-2³¹, 2³¹-1]則夾到邊界。
Example:
Input: s = “42” → 42 Input: s = ” -42” → -42 Input: s = “4193 with words” → 4193 Input: s = “words and 987” → 0 Input: s = “-91283472332” → -2147483648(下溢,夾到 INT_MIN)
Intuition
TIP
核心思路:純粹照規則模擬——指標掃過空白、符號、數字三段。重點在溢位處理:用 Long 累積並在每步檢查是否超界,超界立即夾邊界回傳。
- 三段式:跳空白 → 讀符號 → 讀數字
- 每加一位就檢查是否超過
Int.MAX_VALUE/ 低於Int.MIN_VALUE - 用
Long累積可安全偵測溢位(值最多到 ~2³⁴,仍在 Long 範圍)
Approaches
⭐ Char-by-Char Parse + Long Overflow Check — O(n) / O(1)
- Idea: 指標掃過三段,邊累積邊夾邊界
- Time:
O(n)- 掃描一次 - Space:
O(1)
class Solution {
fun myAtoi(s: String): Int {
val n = s.length
var i = 0
while (i < n && s[i] == ' ') i++ // 1) 跳前導空白
if (i == n) return 0
var sign = 1 // 2) 符號
if (s[i] == '+' || s[i] == '-') {
if (s[i] == '-') sign = -1
i++
}
var result = 0L // 3) 數字 + 溢位夾邊界
while (i < n && s[i].isDigit()) {
result = result * 10 + (s[i] - '0')
if (sign == 1 && result > Int.MAX_VALUE) return Int.MAX_VALUE
if (sign == -1 && -result < Int.MIN_VALUE) return Int.MIN_VALUE
i++
}
return (sign * result).toInt()
}
}Note: Pure-Int Overflow Check (no Long)
若不想用 Long,可在乘 10 前先判斷:當 result > Int.MAX_VALUE / 10,或 result == Int.MAX_VALUE / 10 且下一位 > 7(INT_MAX 末位)時,就會溢位——正負分別夾到 Int.MAX_VALUE / Int.MIN_VALUE。
🔑 Takeaways
- Pattern: 字串模擬,難點不在演算法而在邊界與溢位的嚴謹處理
- Key trick: 三段式掃描(空白/符號/數字)、用 Long 邊累積邊夾邊界最直觀;面試常被追問「不用 Long 怎麼判溢位」,記住「乘 10 前先比 MAX/10」