Reverse Integer (LeetCode 7)
Take a signed 32-bit integer x and flip its digits end to end. If that flipped value would spill outside the signed 32-bit window [-231, 231 - 1], return 0 instead.
Treat 64-bit integer storage (signed or unsigned) as unavailable to you.
Worked Examples
x = 123321123 reversed is 321.x = -123-321-123 becomes -321.x = 12021120 reversed is 021, which is 21.⚖️Formal Constraints & Bounds
-231 <= x <= 231 - 1
Core Insight
Repeatedly pop the last digit via x % 10 and push it onto the reversed result. Before multiplying by 10, check that rev <= (231 - 1) // 10 to avoid 32-bit arithmetic overflow.
Real-World Scenario & Production Applications
Low-level serial communication packet decoding, endianness conversion, hardware register integer serialization.
The Math, Step by Step
1. The two operations that read digits
Every whole number splits into its last digit and the rest:
Here is the remainder after dividing by 10, which is the last digit. is the quotient rounded down, which is with its last digit removed. In Python they are x % 10 and x // 10. For , the last digit is and the rest is .
The reverse step is the opposite: appending a digit to the right of a number gives . So the code reads digits from the right end of x and appends them to the right end of res. This builds the digits in reverse order.
2. One round of the loop
Each round moves one digit from x to res:
| Line | Math | Effect |
|---|---|---|
digit = x % 10 | reads the last digit of x | |
x //= 10 | removes that digit from x | |
res = res * 10 + digit | appends it to res |
The loop runs while x > 0, so it runs once per digit of x.
3. The 32-bit bound, checked before it is crossed
The result must fit in a signed 32-bit integer, which holds values from to . The problem also says to act as if no larger integer type exists. So the code may never compute a value above INT_MAX and check it afterwards. It must decide before the multiplication whether res * 10 + digit would be too large.
Write . Then in exactly two cases:
| Case | Test in the code | Why the new value is too large |
|---|---|---|
res > INT_MAX // 10 | then , which is already too large | |
| and | res == INT_MAX // 10 and digit > 7 | then |
If , then , which fits. If and , the new value is at most , which also fits. So the test is exact. INT_MAX // 10 is , and the 7 is INT_MAX % 10.
4. Why the code takes the absolute value first
Python's % and // round toward minus infinity. So for a negative number, -123 % 10 is 7, not -3, and -123 // 10 is -13, not -12. The digit rule of part 1 would read wrong digits. The code avoids this: it saves sign, reverses abs(x), and multiplies by sign at the end.
The check in part 3 compares against INT_MAX only, even for negative inputs. This is safe for every 32-bit input. res can reach only after 9 digits. The 10th and last digit is then the first digit of x. A 32-bit value has at most 10 digits, and a 10-digit one starts with 1 or 2. So that last digit is never greater than 7. The last line, return res if INT_MIN <= res <= INT_MAX else 0, is a second check of the same bound.
An example where the bound decides: x = 1463847412 reverses to . Before the last round, res is and the digit is 1. Since , the value fits and the code returns . For x = 1534236469, the reversal would be . Before the last round res is , which is greater than . So the code returns 0 without ever computing the large value.
5. Example 1 by hand
x = 123, so sign = 1.
| Round | digit = x % 10 | x after x //= 10 | Check | res = res * 10 + digit |
|---|---|---|---|---|
| 1 | 3 | 12 | , passes | |
| 2 | 2 | 1 | , passes | |
| 3 | 1 | 0 | , passes |
x is now 0, so the loop stops. The code returns , the expected output.
6. Example 2 by hand
x = -123. The code sets sign = -1 and x = 123. The three rounds are the same as in Example 1, so res ends as 321. The code returns , the expected output.
7. From the math to the code
| Math | In reverse |
|---|---|
| and | INT_MAX = 2**31 - 1 and INT_MIN = -2**31 |
| work on , remember the sign | sign = -1 if x < 0 else 1 and x = abs(x) |
| , | digit = x % 10 and x //= 10 |
| , tested before it is computed | if res > INT_MAX // 10 or (res == INT_MAX // 10 and digit > 7): followed by return 0 |
res = res * 10 + digit | |
| put the sign back | res *= sign |
The loop runs once per digit, and a 32-bit value has at most 10 digits. So the code takes time, which is at most 10 rounds, and space.
| 1 | INT_MAX, INT_MIN = 2**31 - 1, -2**31 |
| 2 | sign = -1 if x < 0 else 1 |
| 3 | x = abs(x) |
| 4 | res = 0 |
| 5 | while x > 0: |
| 6 | digit = x % 10 |
| 7 | x //= 10 |
| 8 | if res > INT_MAX // 10 or (res == INT_MAX // 10 and digit > 7): |
| 9 | return 0 |
| 10 | res = res * 10 + digit |
| 11 | res *= sign |
| 12 | return res if INT_MIN <= res <= INT_MAX else 0 |
Conceptual Narrative
Reversing decimal digits of a 32-bit signed integer requires extracting modulo-10 digits and detecting arithmetic overflow before multiplication.
🧭 Conceptual Foundation & Pattern Intuition
Given a 32-bit signed integer , reverse its digits without using 64-bit integers (long). Modulo arithmetic extracts digits: digit = x % 10; x //= 10. The challenge is detecting overflow BEFORE executing res = res * 10 + digit, as exceeding causes integer overflow.
🏟️ The Analogy: The Odometer Stop
Imagine an odometer with a hard physical limit at 2,147,483,647. Before advancing the dial by a factor of 10 and adding a final digit, you verify whether the odometer already reads . If it does, any further addition will break the mechanism.
🔑 Why It Works
Checking against INT_MAX // 10 prevents overflow before it occurs.
Python negative modulo quirk: In Python,
-123 % 10yields7(not-3), and-123 // 10yields-13. Strip the sign withabs(x)first before modulo arithmetic.Post-facto overflow checking: Checking
if res > 2**31 - 1after computingres * 10causes an integer trap/crash in 32-bit hardware. Check bounds before multiplication.Handling the edge case: In C/C++,
abs(-2147483648)exceedsINT_MAXand invokes undefined behavior. Handle explicitly as an overflow case.
4-Phase Thought Process Model
Pattern Recognition Signals
The 10-second spot
Reverse 32-bit signed integer digits, overflow guard [-2^31, 2^31 - 1], return 0 on overflow.
Formulating the Predicate & Invariants
Turning intuition into a boolean rule
Invariant: Accumulating rev = rev * 10 + digit must never exceed (231 - 1) or drop below -231 at any intermediate step.
Silent Failure Traps & Edge Cases
Where confident candidates still lose points
The card's trap: test
res > INT_MAX // 10(orres == INT_MAX // 10anddigit > 7) beforeres * 10 + digit.Asymmetric boundaries:
INT_MAXis2147483647(ends in 7) whileINT_MINis-2147483648(ends in 8), so the blueprint also checks the finalresagainst[INT_MIN, INT_MAX]after the sign is back.The last digit popped is
x's first digit, at most 2 for a 32-bit input, sodigit > 7never fires on this problem; keep it anyway, since it makes the same check correct for any digits, as in a parser.
The 60-Second Interview Pitch
Say this out loud before you type a single line
I'd use Digit Manipulation: take the number apart one digit at a time and rebuild it in reverse, without a string. I save the sign, work on
abs(x), and loop whilex > 0:digit = x % 10reads the last digit,x //= 10drops it, andres = res * 10 + digitappends it on the right. Reading from the right while appending on the right reverses the digits, and working on the absolute value avoids Python's rounding of%and//toward minus infinity for negatives. The trap is overflow. The answer must fit in a 32-bit signed integer, so before the multiply I return 0 ifres > INT_MAX // 10, or ifres == INT_MAX // 10anddigit > 7; checking after the multiply is too late in a fixed-width language, where the product has already wrapped. Each loop drops one digit, so it's O(log10 |x|) time andO(1)space.
Complexity & Mathematical Proof
O(log10 |X|)
Look at the execution steps: Extracts digits via mod 10 and divides by 10 in while loop. Executes at most log10(2^31 - 1) <= 10 iterations. Checks 32-bit signed integer overflow before multiplying by 10. So O(log10 |x|) time, which is at most 10 steps for a 32-bit input, and O(1) space.
O(1) Auxiliary
Look at memory allocations: Call stack uses O(1) Iterative. Single 32-bit integer accumulator register.
T(X) = ⌊ log_{10} |X| ⌋ + 1 ≤ 10 = O(1)
Derivation Progression
digit = x (mod 10), x = x // 10
Pops last digit from integer in O(1).
if rev > (2^{31}-1)/10: return 0
Prevents integer overflow before multiplication in O(1).
≤ 10 iterations
At most 10 decimal digits for 32-bit signed integer.
Variable Definitions
Magnitude of the input integer (at most 10 decimal digits for 32-bit int)
Memory Architecture & Bounds
O(1) Iterative
O(1) Single integer register
O(1) Reversed 32-bit integer
Boundary Best / Worst Cases
for single-digit numbers.
.
(at most 10 iterations).
Pointer Invariant Transition Progression
Senior SWE Deconstruction & Hardware Caveats
The triggers are "reverse digits of a signed 32-bit integer" and "return 0 if reversing causes the value to go outside [-231, 231 - 1]". The junior trap is converting to a string or relying on 64-bit integers (long long in C++ / BigInt in Python), which violates the spirit of 32-bit hardware constraints. A Senior SWE immediately applies Integer Arithmetic Digit Extraction with predictive overflow detection before mutation.
Input is 32-bit signed: . Time budget is operations. Auxiliary space is strictly . Boundary limits: , .
In C and Java, abs(x) itself overflows for : it has no positive 32-bit twin. There, either take the absolute value in 64 bits or keep x negative and work with negative digits (C and Java's % keeps the dividend's sign).
Reverse Integer (LeetCode 7)
Take a signed 32-bit integer x and flip its digits end to end. If that flipped value would spill outside the signed 32-bit window [-231, 231 - 1], return 0 instead.
Treat 64-bit integer storage (signed or unsigned) as unavailable to you.
Worked Examples
x = 123321123 reversed is 321.x = -123-321-123 becomes -321.x = 12021120 reversed is 021, which is 21.⚖️Formal Constraints & Bounds
-231 <= x <= 231 - 1
Core Insight
Repeatedly pop the last digit via x % 10 and push it onto the reversed result. Before multiplying by 10, check that rev <= (231 - 1) // 10 to avoid 32-bit arithmetic overflow.
Real-World Scenario & Production Applications
Low-level serial communication packet decoding, endianness conversion, hardware register integer serialization.
The Math, Step by Step
1. The two operations that read digits
Every whole number splits into its last digit and the rest:
Here is the remainder after dividing by 10, which is the last digit. is the quotient rounded down, which is with its last digit removed. In Python they are x % 10 and x // 10. For , the last digit is and the rest is .
The reverse step is the opposite: appending a digit to the right of a number gives . So the code reads digits from the right end of x and appends them to the right end of res. This builds the digits in reverse order.
2. One round of the loop
Each round moves one digit from x to res:
| Line | Math | Effect |
|---|---|---|
digit = x % 10 | reads the last digit of x | |
x //= 10 | removes that digit from x | |
res = res * 10 + digit | appends it to res |
The loop runs while x > 0, so it runs once per digit of x.
3. The 32-bit bound, checked before it is crossed
The result must fit in a signed 32-bit integer, which holds values from to . The problem also says to act as if no larger integer type exists. So the code may never compute a value above INT_MAX and check it afterwards. It must decide before the multiplication whether res * 10 + digit would be too large.
Write . Then in exactly two cases:
| Case | Test in the code | Why the new value is too large |
|---|---|---|
res > INT_MAX // 10 | then , which is already too large | |
| and | res == INT_MAX // 10 and digit > 7 | then |
If , then , which fits. If and , the new value is at most , which also fits. So the test is exact. INT_MAX // 10 is , and the 7 is INT_MAX % 10.
4. Why the code takes the absolute value first
Python's % and // round toward minus infinity. So for a negative number, -123 % 10 is 7, not -3, and -123 // 10 is -13, not -12. The digit rule of part 1 would read wrong digits. The code avoids this: it saves sign, reverses abs(x), and multiplies by sign at the end.
The check in part 3 compares against INT_MAX only, even for negative inputs. This is safe for every 32-bit input. res can reach only after 9 digits. The 10th and last digit is then the first digit of x. A 32-bit value has at most 10 digits, and a 10-digit one starts with 1 or 2. So that last digit is never greater than 7. The last line, return res if INT_MIN <= res <= INT_MAX else 0, is a second check of the same bound.
An example where the bound decides: x = 1463847412 reverses to . Before the last round, res is and the digit is 1. Since , the value fits and the code returns . For x = 1534236469, the reversal would be . Before the last round res is , which is greater than . So the code returns 0 without ever computing the large value.
5. Example 1 by hand
x = 123, so sign = 1.
| Round | digit = x % 10 | x after x //= 10 | Check | res = res * 10 + digit |
|---|---|---|---|---|
| 1 | 3 | 12 | , passes | |
| 2 | 2 | 1 | , passes | |
| 3 | 1 | 0 | , passes |
x is now 0, so the loop stops. The code returns , the expected output.
6. Example 2 by hand
x = -123. The code sets sign = -1 and x = 123. The three rounds are the same as in Example 1, so res ends as 321. The code returns , the expected output.
7. From the math to the code
| Math | In reverse |
|---|---|
| and | INT_MAX = 2**31 - 1 and INT_MIN = -2**31 |
| work on , remember the sign | sign = -1 if x < 0 else 1 and x = abs(x) |
| , | digit = x % 10 and x //= 10 |
| , tested before it is computed | if res > INT_MAX // 10 or (res == INT_MAX // 10 and digit > 7): followed by return 0 |
res = res * 10 + digit | |
| put the sign back | res *= sign |
The loop runs once per digit, and a 32-bit value has at most 10 digits. So the code takes time, which is at most 10 rounds, and space.
| 1 | INT_MAX, INT_MIN = 2**31 - 1, -2**31 |
| 2 | sign = -1 if x < 0 else 1 |
| 3 | x = abs(x) |
| 4 | res = 0 |
| 5 | while x > 0: |
| 6 | digit = x % 10 |
| 7 | x //= 10 |
| 8 | if res > INT_MAX // 10 or (res == INT_MAX // 10 and digit > 7): |
| 9 | return 0 |
| 10 | res = res * 10 + digit |
| 11 | res *= sign |
| 12 | return res if INT_MIN <= res <= INT_MAX else 0 |
Conceptual Narrative
Reversing decimal digits of a 32-bit signed integer requires extracting modulo-10 digits and detecting arithmetic overflow before multiplication.
🧭 Conceptual Foundation & Pattern Intuition
Given a 32-bit signed integer , reverse its digits without using 64-bit integers (long). Modulo arithmetic extracts digits: digit = x % 10; x //= 10. The challenge is detecting overflow BEFORE executing res = res * 10 + digit, as exceeding causes integer overflow.
🏟️ The Analogy: The Odometer Stop
Imagine an odometer with a hard physical limit at 2,147,483,647. Before advancing the dial by a factor of 10 and adding a final digit, you verify whether the odometer already reads . If it does, any further addition will break the mechanism.
🔑 Why It Works
Checking against INT_MAX // 10 prevents overflow before it occurs.
Python negative modulo quirk: In Python,
-123 % 10yields7(not-3), and-123 // 10yields-13. Strip the sign withabs(x)first before modulo arithmetic.Post-facto overflow checking: Checking
if res > 2**31 - 1after computingres * 10causes an integer trap/crash in 32-bit hardware. Check bounds before multiplication.Handling the edge case: In C/C++,
abs(-2147483648)exceedsINT_MAXand invokes undefined behavior. Handle explicitly as an overflow case.
4-Phase Thought Process Model
Pattern Recognition Signals
The 10-second spot
Reverse 32-bit signed integer digits, overflow guard [-2^31, 2^31 - 1], return 0 on overflow.
Formulating the Predicate & Invariants
Turning intuition into a boolean rule
Invariant: Accumulating rev = rev * 10 + digit must never exceed (231 - 1) or drop below -231 at any intermediate step.
Silent Failure Traps & Edge Cases
Where confident candidates still lose points
The card's trap: test
res > INT_MAX // 10(orres == INT_MAX // 10anddigit > 7) beforeres * 10 + digit.Asymmetric boundaries:
INT_MAXis2147483647(ends in 7) whileINT_MINis-2147483648(ends in 8), so the blueprint also checks the finalresagainst[INT_MIN, INT_MAX]after the sign is back.The last digit popped is
x's first digit, at most 2 for a 32-bit input, sodigit > 7never fires on this problem; keep it anyway, since it makes the same check correct for any digits, as in a parser.
The 60-Second Interview Pitch
Say this out loud before you type a single line
I'd use Digit Manipulation: take the number apart one digit at a time and rebuild it in reverse, without a string. I save the sign, work on
abs(x), and loop whilex > 0:digit = x % 10reads the last digit,x //= 10drops it, andres = res * 10 + digitappends it on the right. Reading from the right while appending on the right reverses the digits, and working on the absolute value avoids Python's rounding of%and//toward minus infinity for negatives. The trap is overflow. The answer must fit in a 32-bit signed integer, so before the multiply I return 0 ifres > INT_MAX // 10, or ifres == INT_MAX // 10anddigit > 7; checking after the multiply is too late in a fixed-width language, where the product has already wrapped. Each loop drops one digit, so it's O(log10 |x|) time andO(1)space.
Complexity & Mathematical Proof
O(log10 |X|)
Look at the execution steps: Extracts digits via mod 10 and divides by 10 in while loop. Executes at most log10(2^31 - 1) <= 10 iterations. Checks 32-bit signed integer overflow before multiplying by 10. So O(log10 |x|) time, which is at most 10 steps for a 32-bit input, and O(1) space.
O(1) Auxiliary
Look at memory allocations: Call stack uses O(1) Iterative. Single 32-bit integer accumulator register.
T(X) = ⌊ log_{10} |X| ⌋ + 1 ≤ 10 = O(1)
Derivation Progression
digit = x (mod 10), x = x // 10
Pops last digit from integer in O(1).
if rev > (2^{31}-1)/10: return 0
Prevents integer overflow before multiplication in O(1).
≤ 10 iterations
At most 10 decimal digits for 32-bit signed integer.
Variable Definitions
Magnitude of the input integer (at most 10 decimal digits for 32-bit int)
Memory Architecture & Bounds
O(1) Iterative
O(1) Single integer register
O(1) Reversed 32-bit integer
Boundary Best / Worst Cases
for single-digit numbers.
.
(at most 10 iterations).
Pointer Invariant Transition Progression
Senior SWE Deconstruction & Hardware Caveats
The triggers are "reverse digits of a signed 32-bit integer" and "return 0 if reversing causes the value to go outside [-231, 231 - 1]". The junior trap is converting to a string or relying on 64-bit integers (long long in C++ / BigInt in Python), which violates the spirit of 32-bit hardware constraints. A Senior SWE immediately applies Integer Arithmetic Digit Extraction with predictive overflow detection before mutation.
Input is 32-bit signed: . Time budget is operations. Auxiliary space is strictly . Boundary limits: , .
In C and Java, abs(x) itself overflows for : it has no positive 32-bit twin. There, either take the absolute value in 64 bits or keep x negative and work with negative digits (C and Java's % keeps the dividend's sign).