LeetCode #8: String to Integer — Solved in Java
Parse with Manual Checks and Structured State Parser with Bounds Check
For this problem you're asked to convert a string into a 32-bit signed integer. That means trimming off any leading spaces, figuring out the sign, grabbing the digits, and stopping once anything non-numeric shows up. If the number goes past the allowed range, you clamp it to the limit.
We will start with a version that’s easy to follow and sticks to what the problem is asking. After that, there’s one more that is better tuned for interviews. Both are broken down line by line, and the final code is ready to copy and run at the end.
LeetCode: String to Integer (atoi)
Implement the
myAtoi(String s)
function, which converts a string to a 32-bit signed integer. Follow these steps:
Ignore leading whitespace
Check for an optional sign
Read in the digits until something invalid shows up
Clamp the result to fit in the range [-2³¹, 2³¹ - 1]
Return the final value
Example 1
Input:
s = "42"
Output:42
Example 2
Input:
s = " -042"
Output:-42
Example 3
Input:
s = "1337c0d3"
Output:1337
Example 4
Input:
s = "0-1"
Output:0
Example 5
Input:
s = "words and 987"
Output:0
Solution 1 — Parse with Manual Checks
Here we follow the problem description directly. It’s a great starting point, especially when you want something simple that just works. It reads the string step by step, skips whitespace, handles the sign, reads digits, and keeps the value within bounds.
Let’s go through it:
class Solution {
public int myAtoi(String s) {
This starts the method and takes in a string. We'll return the parsed integer at the end.
if (s == null || s.length() == 0) return 0;
Check if the input is null or empty. If so, we return 0 right away.
int index = 0, sign = 1, total = 0;
int length = s.length();
We’re setting up some variables. index
tracks where we are, sign
starts positive, and total
holds the number we’re building.
while (index < length && s.charAt(index) == ' ') {
index++;
}
Skip all the leading spaces before looking at the actual number.
if (index < length && (s.charAt(index) == '+' || s.charAt(index) == '-')) {
sign = (s.charAt(index) == '-') ? -1 : 1;
index++;
}
Check for a '+' or '-' sign. If it’s there, we update the sign and move on.
while (index < length && Character.isDigit(s.charAt(index))) {
int digit = s.charAt(index) - '0';
Loop through each digit. We convert each character to an integer by subtracting '0'
.
if (total > (Integer.MAX_VALUE - digit) / 10) {
return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
Before multiplying and adding, we check if doing so would cause an overflow. If it would, we return the limit.
total = total * 10 + digit;
index++;
}
It’s safe, so we update total
and move to the next digit.
return total * sign;
}
}
After we’ve read all the digits, we apply the sign and return the final result.
This runs in O(n) time, where n is the number of characters in the input string. It moves through the string once, checking each character without doing anything extra or repeating steps. Space is O(1) because everything happens using a fixed number of simple variables. There are no new objects or collections being created, just basic control flow and math.
Solution 2 — Structured State Parser with with Bounds Check
This solution is better for interviews. It’s tighter, skips unnecessary checks, and keeps everything organized. Each part of the input is handled once, and there’s no exception handling or type conversion in the middle. It’s all numbers, conditions, and clean loops.
Let’s break it down:
class Solution {
public int myAtoi(String s) {
This defines the method. It takes a string and returns an integer.
int i = 0, n = s.length();
while (i < n && s.charAt(i) == ' ') i++;
Start by skipping any leading spaces. We move i
forward until we find something useful.
if (i == n) return 0;
If we ran out of characters, there’s nothing to parse. Return 0.
int sign = 1;
if (s.charAt(i) == '+' || s.charAt(i) == '-') {
sign = (s.charAt(i) == '-') ? -1 : 1;
i++;
}
Check for a sign. If it's there, we set sign
to -1 or leave it at 1, then move on.
int result = 0;
while (i < n) {
char c = s.charAt(i);
if (c < '0' || c > '9') break;
Now we scan through the digits. If we hit anything that’s not a digit, we stop.
int digit = c - '0';
Turn the digit character into a number.
if (result > (Integer.MAX_VALUE - digit) / 10) {
return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
Before multiplying and adding, we check if it would overflow. If it would, return the clamped value.
result = result * 10 + digit;
i++;
}
If it’s safe, update result
and move on.
return result * sign;
}
}
We apply the sign at the end and return the result.
The solution also runs in O(n) time, scanning the string a single time from left to right. Each character is handled only once, and the logic moves in a straight line without backtracking or extra passes. Space stays O(1) the whole way through, with only a few integers used to track the index, the sign, and the result. No strings, arrays, or maps are created along the way. It's compact and efficient without sacrificing clarity.
Parse with Manual Checks — Copy and Paste
class Solution {
public int myAtoi(String s) {
if (s == null || s.length() == 0) return 0;
int index = 0, sign = 1, total = 0;
int length = s.length();
while (index < length && s.charAt(index) == ' ') {
index++;
}
if (index < length && (s.charAt(index) == '+' || s.charAt(index) == '-')) {
sign = (s.charAt(index) == '-') ? -1 : 1;
index++;
}
while (index < length && Character.isDigit(s.charAt(index))) {
int digit = s.charAt(index) - '0';
if (total > (Integer.MAX_VALUE - digit) / 10) {
return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
total = total * 10 + digit;
index++;
}
return total * sign;
}
}
Structured State Parser with Bounds Check — Copy and Paste
class Solution {
public int myAtoi(String s) {
int i = 0, n = s.length();
while (i < n && s.charAt(i) == ' ') i++; // skip whitespace
if (i == n) return 0;
int sign = 1;
if (s.charAt(i) == '+' || s.charAt(i) == '-') {
sign = (s.charAt(i) == '-') ? -1 : 1;
i++;
}
int result = 0;
while (i < n) {
char c = s.charAt(i);
if (c < '0' || c > '9') break;
int digit = c - '0';
// clamp before overflow
if (result > (Integer.MAX_VALUE - digit) / 10) {
return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
result = result * 10 + digit;
i++;
}
return result * sign;
}
}