-
Notifications
You must be signed in to change notification settings - Fork 0
180 — Reverse Integer
LeetCode 7 · Medium. Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range ([-2147483648, 2147483647]), return 0.
Reversing the digits of a number is a much more familiar operation than reversing its bits — it's the same thing you'd do turning 123 into 321 by hand, just done on a computer. The most direct way to do that: write the number out as a string, flip the sign aside for a moment, reverse the string of digits, and read it back as a number. Swift's String and Int conversions make that almost free. The one wrinkle the problem insists on is that the result has to still fit inside a signed 32-bit integer — reversing a big enough number can produce something too large to represent, and the problem wants 0 back in that case rather than a silently wrong answer. So whichever way you compute the reversal, the last step is always the same: check the result against the 32-bit signed bounds before handing it back.
x = -123
sign: negative
digits (absolute value): "123"
reversed digits: "321"
re-apply sign: -321
-321 is well within [-2147483648, 2147483647] -> return -321
x = 1534236469
reversed digit-by-digit -> 9646324351
9646324351 > 2147483647 (Int32.max) -> overflow -> return 0
"Reverse the digits, return 0 on 32-bit overflow" is the signal to treat the number as a sequence of base-10 digits rather than as a bit pattern — peel or read digits from one end and rebuild from the other, and always compare the in-progress or final result against Int32.min/Int32.max rather than letting an overflow happen silently.
Convert the absolute value to a String, reverse that string, parse it back into an integer, then re-apply the original sign and check the result against the signed 32-bit bounds.
func reverseBruteForce(_ x: Int) -> Int {
let isNegative = x < 0
let digits = String(abs(x))
let reversedDigits = String(digits.reversed())
guard let reversedMagnitude = Int(reversedDigits) else { return 0 }
let result = isNegative ? -reversedMagnitude : reversedMagnitude
if result < Int(Int32.min) || result > Int(Int32.max) {
return 0
}
return result
}
// smoke test
print(reverseBruteForce(123)) // 321
print(reverseBruteForce(-123)) // -321
print(reverseBruteForce(120)) // 21
print(reverseBruteForce(1534236469)) // 0 (reversed value 9646324351 overflows Int32)Big-O: O(d) time where d is the number of digits (at most 10 for a 32-bit integer), for the string conversion, reversal, and parse. O(d) extra space for the string representations.
Pop digits off x one at a time with % 10 and / 10, pushing each one into a running result — checking before every multiply-and-add whether it would push the result past the 32-bit signed bounds, so overflow is caught pre-emptively instead of after the fact.
func reverse(_ x: Int) -> Int {
let int32Max = Int(Int32.max) // 2147483647
let int32Min = Int(Int32.min) // -2147483648
var x = x
var result = 0
while x != 0 {
let digit = x % 10
x /= 10
if result > int32Max / 10 || (result == int32Max / 10 && digit > 7) {
return 0
}
if result < int32Min / 10 || (result == int32Min / 10 && digit < -8) {
return 0
}
result = result * 10 + digit
}
return result
}
// smoke test — same cases as the brute force
print(reverse(123)) // 321
print(reverse(-123)) // -321
print(reverse(120)) // 21
print(reverse(1534236469)) // 0Big-O: O(d) time where d is the number of digits, same as the brute force — one % 10 / / 10 pair per digit. O(1) extra space — no string is ever built.
The brute force leans entirely on String and Int conversions to do the reversing and to sidestep overflow — because Swift's Int is 64 bits wide, parsing the reversed digit string back into an Int never actually overflows during the parse itself, so the overflow check only needs to happen once, at the very end, against the 32-bit bounds. The optimal solution builds the same result numerically instead of textually, popping and pushing digits with plain arithmetic — but since it's also using a 64-bit Int under the hood, it has to explicitly compare against Int32.max / Int32.min before each digit is folded in, rather than relying on an actual overflow trap to catch the problem. Both solutions ultimately do the same bounds check; they just differ in whether the reversal itself happens through text or through arithmetic.
%// and rebuilding a number — is digit arithmetic, not bit manipulation in the XOR/shift sense. NeetCode groups it under Bit Manipulation because the difficulty that actually matters here is reasoning precisely about 32-bit integer bounds (Int32.min/Int32.max), which is bit-width-adjacent even though no XOR, AND, or shift ever appears in the solution. Worth naming plainly rather than pretending this is secretly a bitwise trick in disguise.
-
Arrays and Strings — the brute force's
Stringrepresentation of the number, reversed and reparsed exactly like reversing any other array of characters. -
Bit Manipulation Tricks — disclosed as a stretch, not a bitwise trick: this chapter's own techniques (digit-popping with
%//, string reversal) do no XOR or shift work at all. The link holds only because reasoning about signed 32-bit bounds (Int32.min/Int32.max) is the same bit-width discipline this pattern chapter covers for genuinely bitwise problems — not because the code itself is a bit trick.
Reverse Integer is flipping a number's digits like flipping a string — the only real trap is checking the 32-bit signed bounds before the reversed value slips outside them.
- Why does the brute force need to strip the sign off with
abs(x)before reversing the string, rather than reversing the string representation ofxdirectly (including a possible-character)? - Walk through why
reverse(120)returns21and not021or0021— what part of the process silently drops the leading zero? - In the optimal solution, why is the overflow check performed before
result = result * 10 + digitrather than after? What would go wrong if you computed the new result first and checked its bounds afterward, given that Swift'sIntis 64 bits wide? - The chapter discloses that this problem's link to Bit Manipulation Tricks is a stretch. If you had to categorize Reverse Integer purely by its technique rather than by NeetCode's grouping, which pattern chapter would you place it under instead, and why?