Cracking LeetCode 7: How to Reverse an Integer Safely (and Why It's Tricky!)
Hey awesome developers! 👋 Welcome back to another exciting LeetCode breakdown with aaradhyanegi009. Today, we're diving into a classic problem that seems simple on the surface but hides a crucial twist: Reversing an Integer. It's a fantastic exercise for understanding integer manipulation and, more importantly, how to deal with the dreaded "integer overflow."
Let's get started!
🚀 Problem Explanation: Reverse Integer (LeetCode #7)
You're given a signed 32-bit integer, let's call it x. Your task is to return this integer with its digits reversed. Sounds easy, right?
Here's the catch:
- Signed 32-bit integer range: This means
xcan be anywhere from -2,147,483,648 to 2,147,483,647. - Overflow Check: If the reversed version of
xgoes outside this 32-bit signed integer range, you must return0. - No 64-bit integers (for final result): You're assumed not to be able to store 64-bit integers. This implies that your final return value should fit within a 32-bit integer, and you need clever ways to detect overflow without relying on a larger type for the final result.
Let's look at some examples:
-
Example 1:
x = 123- Output:
321(Simple reversal)
- Output:
-
Example 2:
x = -123- Output:
-321(Negative sign needs to be preserved)
- Output:
-
Example 3:
x = 120- Output:
21(Trailing zeros become leading zeros and disappear)
- Output:
💡 Intuition: The "Aha!" Moment
When you think about reversing digits, two main strategies often come to mind:
Mathematical Approach: Repeatedly extract the last digit (
x % 10), build the reversed number (reversed = reversed * 10 + digit), and truncatex(x /= 10). This is efficient but makes overflow checking a bit more intricate, as you need to check before each multiplication.String Conversion Approach: Convert the number to a string, reverse the string, and then convert it back to a number. This often feels more intuitive for reversing sequences and can simplify overflow detection, as you perform the reversal first and then check the final value.
For this problem, especially given the "no 64-bit integers" constraint (which is often interpreted as "don't return a 64-bit integer, but you might use it temporarily for safety checks"), the string conversion approach combined with careful type handling provides a very robust and readable solution.
The "aha!" here is realizing that a long long (which is typically 64-bit) can be your best friend for intermediate calculations and overflow checks, even if your final answer must fit in an int (32-bit). You build the potentially overflowing number in a long long, then compare it against the INT_MAX and INT_MIN boundaries before casting it back to an int. This way, you catch overflows safely.
📋 Approach: Step-by-Step Logic
Our chosen approach leverages string manipulation for the reversal and long long for safe overflow detection.
-
Preserve the Sign and Get Absolute Value:
- First, we need to know if the original
xwas negative. We'll store its sign and work with its absolute value. This simplifies the reversal process, as we don't have to worry about the negative sign until the very end. - We store
xin along longvariable (val) right away to prevent any potential overflow issues ifxitself isINT_MIN(which behaves strangely withabs()in some contexts).
- First, we need to know if the original
-
Convert to String:
- Convert the absolute value of
valinto astring. This allows us to easily manipulate its digits. Forx = 123,numbecomes"123". Forx = -123,numbecomes"123".
- Convert the absolute value of
-
Reverse the String:
- Use a standard library function (like
std::reversein C++) to reverse thenumstring."123"becomes"321", and"12"becomes"21".
- Use a standard library function (like
-
Convert Back to Number (Safely!):
- Convert the reversed string back into a numerical type. Here's where
long longshines! We convert it into along long(res) usingstoll()(string to long long). This letsrestemporarily hold values larger thanINT_MAXor smaller thanINT_MINwithout crashing, so we can then check them.
- Convert the reversed string back into a numerical type. Here's where
-
Reapply the Original Sign:
- If the original
xwas negative (checked byx < 0), multiply ourresby-1to restore its negative sign.
- If the original
-
Perform Overflow Check:
- Now that we have the final
resas along long, we compare it against theINT_MAX(2,147,483,647) andINT_MIN(-2,147,483,648) limits. - If
resis greater thanINT_MAXor less thanINT_MIN, it means the reversed integer overflows a 32-bit signed integer. In this case, as per the problem, we return0.
- Now that we have the final
-
Return the Result:
- If no overflow occurred, we know
resperfectly fits into a 32-bit integer. We castresto anintand return it.
- If no overflow occurred, we know
This approach gracefully handles negative numbers, trailing zeros, and the all-important overflow condition, while respecting the underlying 32-bit integer limits for the final result.
💻 Code
Here's the C++ implementation following our approach:
#include <string> // Required for std::string, to_string, stoll
#include <algorithm> // Required for std::reverse
#include <limits> // Required for INT_MAX, INT_MIN (or just use <climits>)
class Solution {
public:
int reverse(int x) {
// Use INT_MAX and INT_MIN from <limits> for clarity
// Or directly use numeric_limits<int>::max() / min()
int max_V = std::numeric_limits<int>::max();
int min_V = std::numeric_limits<int>::min();
// Use long long to safely store x initially.
// This is crucial for handling INT_MIN correctly with abs() if used directly.
long long val = x;
// 1. Convert absolute value of the number to a string
// abs() ensures we work with positive digits first
std::string num = std::to_string(std::abs(val));
// 2. Reverse the string
std::reverse(num.begin(), num.end());
// 3. Convert the reversed string back to a long long.
// This allows us to temporarily hold a value that might exceed int limits
// before we perform the overflow check.
long long res = std::stoll(num);
// 4. Reapply the original sign
if (x < 0) {
res *= -1;
}
// 5. Check for 32-bit integer overflow/underflow
if (res > max_V || res < min_V) {
return 0; // Return 0 if the reversed integer is out of range
}
// 6. If no overflow, cast the long long result back to int and return
return static_cast<int>(res);
}
};
⏱️ Time & Space Complexity Analysis
Let's break down the efficiency of this solution:
Time Complexity: O(log10(x)) or O(1)
-
std::to_string(std::abs(val)): The time taken to convert an integer to a string is proportional to the number of digits in the integer. IfDis the number of digits inx, this isO(D). -
std::reverse(num.begin(), num.end()): Reversing a string of lengthDtakesO(D)time. -
std::stoll(num): Converting a string back to along longalso takes time proportional to the number of digits,O(D).
For a 32-bit integer, the maximum number of digits is 10 (e.g., 2,147,483,647). Since D is effectively a constant for fixed-size integers, the operations are constant time relative to the number of digits. Therefore, the overall time complexity is often considered O(1) for practical purposes in competitive programming context where the input integer's size is fixed (32-bit). If we consider x to be arbitrarily large, it would be O(log10(x)).
Space Complexity: O(log10(x)) or O(1)
-
std::string num: We create a string to store the digits ofx. The length of this string isD, the number of digits inx.
Similar to time complexity, for a 32-bit integer, D is at most 10, making the space usage effectively constant. Thus, the space complexity is often considered O(1). If x were arbitrarily large, it would be O(log10(x)).
✨ Key Takeaways
- String Power: Don't underestimate the power of string conversions for digit-based problems. They can simplify complex logic like reversal and often offer good readability.
- Overflow is King: In integer problems, handling overflow is paramount. Always consider the data type limits (
INT_MAX,INT_MIN) and how your operations might exceed them. - Temporary
long long(or Wider Types): Even if the problem constraints state that the final result must fit into a smaller type (likeint), you can often use a wider type (long long) for intermediate calculations or for checking potential overflow before clamping the final result. This is a common and safe pattern. - Edge Cases: Always test with edge cases like negative numbers (
-123), numbers ending in zero (120), and boundary values (INT_MAX,INT_MIN, or their reversed versions if they exist).
This problem serves as an excellent reminder that even seemingly simple tasks can have hidden complexities, pushing us to write more robust and error-resistant code. Keep coding, keep learning!
Authored by aaradhyanegi009 | Published on 2026-05-18 06:29:57
Top comments (0)