C++ 0008.cpp
class Solution {
public:
int myAtoi(string s) {
while (!s.empty() && s[0] == ' ')
s.erase(s.begin());
if (s.empty())
return 0;
bool isNeg = false;
if (s[0] == '+')
{
s.erase(s.begin());
}
else if (s[0] == '-')
{
isNeg = true;
s.erase(s.begin());
}
int64_t x = 0;
while (!s.empty() && s[0] >= '0' && s[0] <= '9')
{
auto digit = s[0] - '0';
s.erase(s.begin());
x = x*10 + digit;
if (x > std::numeric_limits<int>::max())
break;
}
if (isNeg)
{
x = -x;
x = max<int64_t>(std::numeric_limits<int>::min(), x);
}
else
{
x = min<int64_t>(std::numeric_limits<int>::max(), x);
}
return x;
}
};
Difficulty
and has an acceptance rate of about 21% (10+ million submissions).
Typical patterns to solve this problem:
- String
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The implementation converts a character sequence into a 32-bit signed integer while respecting the rules of the classic “atoi” problem. It processes the input string step-by-step: discarding leading blanks, detecting an optional sign, accumulating decimal digits, and finally clamping the result to the range of a signed 32-bit integer. The code relies on standard library utilities for limits and for safe arithmetic in a wider type.
Trimming Leading Whitespace
The first loop removes any leading space characters. By repeatedly erasing the first element while it is a space, the string is reduced to its first non-space character or becomes empty.
while (!s.empty() && s[0] == ' ')
s.erase(s.begin());
If the string becomes empty after this step, the function returns zero, handling the case where the input consists solely of whitespace.
Sign Detection
After whitespace removal, the code checks for an explicit ‘+’ or ‘-’ sign. A boolean flag records negativity. When a sign character is present, it is removed from the string so that subsequent processing sees only the digit sequence.
bool isNeg = false;
if (s[0] == '+')
{
s.erase(s.begin());
}
else if (s[0] == '-')
{
isNeg = true;
s.erase(s.begin());
}
This logic correctly treats a missing sign as positive and ensures that a sign without following digits still results in zero after the digit-parsing loop.
Digit Accumulation
The core conversion loop reads characters while they are decimal digits. Each digit is transformed from its ASCII code to a numeric value, the running total is multiplied by ten, and the digit is added. The accumulator x is a 64-bit integer, which prevents overflow during the multiplication and addition steps.
int64_t x = 0;
while (!s.empty() && s[0] >= '0' && s[0] <= '9')
{
auto digit = s[0] - '0';
s.erase(s.begin());
x = x*10 + digit;
if (x > std::numeric_limits<int>::max())
break;
}
The loop stops early if the intermediate value exceeds the maximum 32-bit signed integer, preventing unnecessary work on the remaining characters.
Clamping to 32-Bit Range
After digit collection, the sign is applied. For a negative result, the code negates the accumulator and then clamps it to the lower bound of a 32-bit signed integer. For a positive result, it clamps to the upper bound. The max and min functions guarantee that the final value never exceeds the representable range.
if (isNeg)
{
x = -x;
x = max<int64_t>(std::numeric_limits<int>::min(), x);
}
else
{
x = min<int64_t>(std::numeric_limits<int>::max(), x);
}
The function then returns the clamped value as an int.
Edge Cases Handled
The algorithm gracefully handles an input that is empty after whitespace removal, returning zero. It also correctly processes strings that contain only a sign character without digits, again yielding zero because the digit loop never executes. Non-digit characters that appear after the numeric prefix cause the digit loop to stop, leaving the already-parsed portion as the result. Overflow is prevented by the early break in the accumulation loop and by the final clamping step, ensuring that values larger than INT_MAX become INT_MAX and values smaller than INT_MIN become INT_MIN.
Performance Optimizations
The code avoids repeated conversion of the entire string by operating directly on the mutable std::string. Erasing the first character after it has been processed eliminates the need for an index variable and keeps the loop conditions simple. Using a 64-bit accumulator sidesteps overflow checks inside the multiplication, allowing the loop to run with minimal arithmetic overhead. The early exit when the accumulator exceeds INT_MAX reduces the number of iterations for very long numeric prefixes, saving time on inputs that would otherwise be truncated. Finally, the use of std::numeric_limits provides compile-time constants for the bounds, avoiding any runtime calculation of the limits.
ELI5 - Simplified Explanation
Imagine this code is like a tiny robot that is an expert at finding hidden numbers inside a messy pile of text. When you give the robot a jumbled string, it starts by sweeping away any empty spaces at the very front, just like clearing away dust so it can see clearly.
Once the front is clean, the robot peeks at the first character to see if it has a special sign. If it sees a plus sign, it ignores it because numbers are positive by default. If it sees a minus sign, it makes a little mental note that the final answer needs to be turned into a negative number.
After checking for the sign, the robot looks for the actual digits. It picks up each number character one by one and turns it into a real math number. Every time it finds a new number, it multiplies what it already has by ten and adds the new digit to the end, just like building a tower taller by stacking blocks one at a time. It keeps doing this until it runs out of numbers or hits a character that is not a digit.
Finally, the robot has to be careful because sometimes a very long string might try to make a number way too big for it to hold. If the number creates a tower that is too tall, the robot chops it down to the largest or smallest size that fits safely in its memory. If the robot made a note that the number should be negative, it flips the sign and makes sure it stays within the allowed limits so everything stays neat and tidy.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | |||||||||||||
| www | AlgoMonster | C++ | Python | Java | TS | |||||||||
| WalkCCC | C++ | Python | Java | |||||||||||
| leetcode.ca | C++ | C | Python | Java | C# | JS | Go | PHP | ||||||
| LeetcodeHelp | C++ | Python | Java | |||||||||||
| MemoryLimitExceeded | C++ | Python | ||||||||||||
| Progiez | C++ | Python | Java | |||||||||||
| github | aylei | Rust | ||||||||||||
| begeekmyfriend | C | |||||||||||||
| BigEggStudy | C# | |||||||||||||
| black-shadows | C++ | |||||||||||||
| charles-wangkai | Java | |||||||||||||
| everthis | JS | |||||||||||||
| fartem | Ruby | |||||||||||||
| fengvyi | C++ | |||||||||||||
| gaosq0604 | Python | |||||||||||||
| Garvit244 | Python | |||||||||||||
| halfrost | Go | |||||||||||||
| haoel | C++ | |||||||||||||
| JoshCrozier | JS | |||||||||||||
| Krazune | C | |||||||||||||
| lennylxx | C | |||||||||||||
| linouk23 | C++ | |||||||||||||
| lkwq007 | Python | |||||||||||||
| luangong | C++ | |||||||||||||
| MacJim | C++ | |||||||||||||
| qiyuangong | Java | |||||||||||||
| ruoru | Rust | |||||||||||||
| Shamik07 | Dart | |||||||||||||
| shreymehul | C# | |||||||||||||
| sonugiri1043 | C++ | |||||||||||||
| suxrobGM | C# | |||||||||||||
| varunu28 | Java | |||||||||||||
| vli02 | C | |||||||||||||
| XiaotaoGuo | C++ | |||||||||||||
| yuanliu666 | Kotlin | |||||||||||||
| zfang399 | C++ | |||||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||||||||
| WalkCCC | C++, Python, Java | |||||||||||||
| leetcode.ca | C, C++, C#, Go, Java, JavaScript, PHP, Python | |||||||||||||
| LeetcodeHelp | C++, Java, Python | |||||||||||||
| MemoryLimitExceeded | Python, C++ | |||||||||||||
| Progiez | C++, Java, Python | |||||||||||||
| aylei | Rust | |||||||||||||
| begeekmyfriend | C | |||||||||||||
| BigEggStudy | C# | |||||||||||||
| black-shadows | C++, C++ | |||||||||||||
| charles-wangkai | Java | |||||||||||||
| everthis | JavaScript | |||||||||||||
| fartem | Ruby | |||||||||||||
| fengvyi | C++ | |||||||||||||
| gaosq0604 | Python | |||||||||||||
| Garvit244 | Python | |||||||||||||
| halfrost | Go | |||||||||||||
| haoel | C++ | |||||||||||||
| JoshCrozier | JavaScript | |||||||||||||
| Krazune | C | |||||||||||||
| lennylxx | C | |||||||||||||
| linouk23 | C++ | |||||||||||||
| lkwq007 | Python | |||||||||||||
| luangong | C++ | |||||||||||||
| MacJim | C++ | |||||||||||||
| qiyuangong | Java | |||||||||||||
| ruoru | Rust | |||||||||||||
| Shamik07 | Dart | |||||||||||||
| shreymehul | C# | |||||||||||||
| sonugiri1043 | C++ | |||||||||||||
| suxrobGM | C# | |||||||||||||
| varunu28 | Java | |||||||||||||
| vli02 | C | |||||||||||||
| XiaotaoGuo | C++ | |||||||||||||
| yuanliu666 | Kotlin | |||||||||||||
| zfang399 | C++ |
Videos
Similar Problems
- problem 7: Reverse Integer
- problem 65: Valid Number
Solved On The Same Day
- problem 1: Two Sum
- problem 9: Palindrome Number
- problem 14: Longest Common Prefix
- problem 20: Valid Parentheses
- problem 26: Remove Duplicates from Sorted Array
- problem 27: Remove Element
- problem 83: Remove Duplicates from Sorted List
- problem 88: Merge Sorted Array
- problem 94: Binary Tree Inorder Traversal
- problem 100: Same Tree
- problem 104: Maximum Depth of Binary Tree
- problem 121: Best Time to Buy and Sell Stock
- problem 136: Single Number
- problem 141: Linked List Cycle
- problem 169: Majority Element
- problem 190: Reverse Bits
- problem 226: Invert Binary Tree
- problem 234: Palindrome Linked List
- problem 1114: Print in Order
- problem 3: Longest Substring Without Repeating Characters
- problem 7: Reverse Integer
- problem 11: Container With Most Water
- problem 12: Integer to Roman
- problem 15: 3Sum
- problem 17: Letter Combinations of a Phone Number
- problem 22: Generate Parentheses
- problem 31: Next Permutation
- problem 36: Valid Sudoku
- problem 39: Combination Sum
- problem 40: Combination Sum II
- problem 45: Jump Game II
- problem 46: Permutations
- problem 47: Permutations II
- problem 48: Rotate Image
- problem 49: Group Anagrams
- problem 55: Jump Game
- problem 59: Spiral Matrix II
- problem 75: Sort Colors
- problem 77: Combinations
- problem 91: Decode Ways
- problem 95: Unique Binary Search Trees II
- problem 96: Unique Binary Search Trees
- problem 134: Gas Station
- problem 164: Maximum Gap
- problem 189: Rotate Array
- problem 215: Kth Largest Element in an Array
- problem 238: Product of Array Except Self
- problem 287: Find the Duplicate Number
- problem 322: Coin Change
- problem 347: Top K Frequent Elements
- problem 377: Combination Sum IV
- problem 438: Find All Anagrams in a String
- problem 474: Ones and Zeroes
- problem 518: Coin Change II
- problem 526: Beautiful Arrangement
- problem 763: Partition Labels
- problem 983: Minimum Cost For Tickets
- problem 994: Rotting Oranges
- problem 1027: Longest Arithmetic Subsequence
- problem 2140: Solving Questions With Brainpower
- problem 2466: Count Ways To Build Good Strings
- problem 4: Median of Two Sorted Arrays
- problem 41: First Missing Positive
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality