String to Integer (atoi)
Skip whitespace, parse optional sign, consume digits with overflow clamp.
4 min read
string parsing math
Problem#
Implement a parser that converts a string to a 32-bit signed integer (clamp to [-2^31, 2^31-1] on overflow). Skip leading whitespace, parse optional sign, consume the digit run.
Examples#
"42"→42." -42"→-42;"4193 with words"→4193;"words and 987"→0.
Constraints#
0 <= s.length <= 200.
Approach#
Skip whitespace. Consume optional sign. Parse digits, clamping at each step before multiplying by 10.
Solution#
class Solution {public: int myAtoi(string s) { int i = 0, n = s.size(); while (i < n && s[i] == ' ') ++i; int sign = 1; if (i < n && (s[i] == '+' || s[i] == '-')) { if (s[i] == '-') sign = -1; ++i; } long long ans = 0; while (i < n && isdigit(s[i])) { ans = ans * 10 + (s[i] - '0'); if (sign * ans > INT_MAX) return INT_MAX; if (sign * ans < INT_MIN) return INT_MIN; ++i; } return (int)(sign * ans); }};import "math"
func myAtoi(s string) int { i, n := 0, len(s) for i < n && s[i] == ' ' { i++ } sign := 1 if i < n && (s[i] == '+' || s[i] == '-') { if s[i] == '-' { sign = -1 } i++ } var ans int64 for i < n && s[i] >= '0' && s[i] <= '9' { ans = ans*10 + int64(s[i]-'0') if int64(sign)*ans > math.MaxInt32 { return math.MaxInt32 } if int64(sign)*ans < math.MinInt32 { return math.MinInt32 } i++ } return int(int64(sign) * ans)}class Solution: def myAtoi(self, s: str) -> int: INT_MAX, INT_MIN = (1 << 31) - 1, -(1 << 31) i, n = 0, len(s) while i < n and s[i] == ' ': i += 1 sign = 1 if i < n and s[i] in '+-': if s[i] == '-': sign = -1 i += 1 ans = 0 while i < n and s[i].isdigit(): ans = ans * 10 + (ord(s[i]) - ord('0')) if sign * ans > INT_MAX: return INT_MAX if sign * ans < INT_MIN: return INT_MIN i += 1 return sign * ansfunction myAtoi(s) { const INT_MAX = 2147483647; const INT_MIN = -2147483648; let i = 0; const n = s.length; while (i < n && s[i] === ' ') i++; let sign = 1; if (i < n && (s[i] === '+' || s[i] === '-')) { if (s[i] === '-') sign = -1; i++; } let ans = 0; while (i < n && s[i] >= '0' && s[i] <= '9') { ans = ans * 10 + (s.charCodeAt(i) - 48); if (sign * ans > INT_MAX) return INT_MAX; if (sign * ans < INT_MIN) return INT_MIN; i++; } return sign * ans;}class Solution { public int myAtoi(String s) { int i = 0, n = s.length(); while (i < n && s.charAt(i) == ' ') i++; int sign = 1; if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) { if (s.charAt(i) == '-') sign = -1; i++; } long ans = 0; while (i < n && Character.isDigit(s.charAt(i))) { ans = ans * 10 + (s.charAt(i) - '0'); if (sign * ans > Integer.MAX_VALUE) return Integer.MAX_VALUE; if (sign * ans < Integer.MIN_VALUE) return Integer.MIN_VALUE; i++; } return (int) (sign * ans); }}function myAtoi(s: string): number { const INT_MAX = 2147483647; const INT_MIN = -2147483648; let i = 0; const n = s.length; while (i < n && s[i] === ' ') i++; let sign = 1; if (i < n && (s[i] === '+' || s[i] === '-')) { if (s[i] === '-') sign = -1; i++; } let ans = 0; while (i < n && s[i] >= '0' && s[i] <= '9') { ans = ans * 10 + (s.charCodeAt(i) - 48); if (sign * ans > INT_MAX) return INT_MAX; if (sign * ans < INT_MIN) return INT_MIN; i++; } return sign * ans;}Editorial#
Using long long for the accumulator lets us multiply by 10 and add a digit without immediate overflow; the per-step clamp catches any value beyond int range as it’s being built. Whitespace and sign are each parsed at most once.
Complexity#
- Time:
O(n). - Space:
O(1).
Concept revision#
Related#