3 minutes
Leetcode 8
I am going to explain this solution while walking through the code:
- We can first remove the starting spaces because the problem says to “Read in and ignore any leading whitespace”.
- Then, my code checks whether the length of
sequals0. If it is, we can return0, because some of the following code is hardcoded toshaving a minimum length of1. - Then, if the first character is negative or positive, we can account for the sign:
- We can check for a positive or negative sign once throughout this whole code right before the digits because a positive/negative sign should only be there.
- If it is a negative sign, we can make a variable called
negequal to negative 1, so we can multiply the result bynegto get the result negative. We can’t multiplyres(resis the result) by-1right when we find the negative sign becauseresstarts at0, and0 * -1 = 0(No difference). - Then, if it is a positive or negative sign, we can move the start position up by one because we don’t want to count a
'+', or'-'as a digit.
- After that, we have to loop throught the remains at the string, starting at our start position.
- Let us call the character we are on
charto be consistent. - We also check whether
res > 2147483647, I will come back to the reason for this later. - Next, we can check whether
charis a digit using ASCII, and if it is a digit, we can do:
res = res * 10 + int(char - '0')
This can be expanded into:
res *= 10
res += int(char - '0')
I can explain this by using the example 15461, and we are adding the digit 1 to the end to get 154611.
If we add 1 to 15461, we get 15462, instead of the expected 154611. But let us say that we multiply 15461 by 10, we get 154610, and then we add 1 we get 154611.
- Continuing with the walkthrough, if the character is not a digit, we know that we can break out of the loop.
- After the loop has finished, we can multiply
resbyneg(neg = 1if it is a positive sign or no sign andneg = -1if there is a negative sign). - Then, if res is out of 32-bit signed integer range, we can clamp it down.
Now we can get back to the res > 2147483647 part inside the loop. On one of the test cases, the string s was "9223372036854775808", and when I looped through s and made it into an integer, I hit the 31’st bit and turned res into a negative number, so I output -2147483648. To fix this, I decided to break if res has passed over the boundary of 2147483647, so this never happens. I don’t check if res > 2147483647 || res < -2147483648 because res will never be negative (This is because we haven’t made res negative yet).
The Code:
func myAtoi(s string) int {
s = strings.TrimLeft(s, " ")
res := 0
neg := 1
i := 0
if len(s) == 0 {
return 0
}
if s[0] == '-' {
neg = -1
i++
} else if s[0] == '+' {
i++
}
for i < len(s) {
char := s[i]
i++
if res > 2147483647 {
break
}
if int(char - '0') > -1 && int(char - '0') < 10 {
res = res * 10 + int(char - '0')
continue
}
break
}
res *= neg
if res < -2147483648 {return -2147483648} // -2^31
if res > 2147483647 {return 2147483647} // 2^31 - 1
return res
}