Solved this:
Implement atoi to convert a string to an integer.
Requirements for atoi:
The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.
The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.
If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.
If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.
Solution:
Check if string is null first then empty, if either is true, return 0. Keep iterating through string until we hit the first non-empty space character.
From this position, we check if the first character is '+' or '-'. If so, we move the iterator by one step and note the sign in boolean isNegative
.
From the current position, as long as the character is an integer, we add it to solution
while checking for overflow each time we do so. We keep iterating through the string until we hit a non-integer character and return solution
:
class Solution {
boolean isNegative = false;
int i = 0; // string iterator position
public int myAtoi(String str) {
int solution = 0;
if (str == null || str.isEmpty()) {
return 0;
}
while (i < str.length() && str.charAt(i) == ' ') {
i++; // discard leading whitespace
}
checkSign(str);
for (; i < str.length(); i++) {
if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
int prev = solution; // keep solution from last iter to check for overflow
solution = solution*10; // move number left one position
solution = solution+(str.charAt(i)-'0'); // increase solution by curr integer
if (isOverflow(prev, solution)) {
if (isNegative) {
return Integer.MIN_VALUE;
}
return Integer.MAX_VALUE;
}
} else {
return signSolution(solution); // we've reached a non-integer character before end of string
}
}
return signSolution(solution); // last character of string is an integer
}
boolean isOverflow(int prev, int curr) {
// prev = value at last iteration
// curr = value after current iteration
if (curr/10 == prev) {
return false;
}
return true;
}
void checkSign(String str) {
if (str.charAt(i) == '+') {
i++;
} else if (str.charAt(i) == '-') {
isNegative = true;
i++;
}
}
int signSolution(int solution) {
if (isNegative) {
return solution*-1;
}
return solution;
}
}
isOverflow()
method is pretty clever. However, you might be able to make the calculation more efficient by exploiting two's complement arithmetic. For example, when a positive two's complement number overflows, it becomes negative. \$\endgroup\$