title: A Number After a Double Reversal slug: a-number-after-a-double-reversal difficulty: easy leetcode_id: 2119 leetcode_url: https://leetcode.com/problems/a-number-after-a-double-reversal/ categories: - math patterns: - greedy description: | **Reversing** an integer means to reverse all its digits. - For example, reversing `2021` gives `1202`. Reversing `12300` gives `321` as the **leading zeros are not retained**. Given an integer `num`, **reverse** `num` to get `reversed1`, then **reverse** `reversed1` to get `reversed2`. Return `true` *if* `reversed2` *equals* `num`. Otherwise return `false`. constraints: | - `0 <= num <= 10^6` examples: - input: "num = 526" output: "true" explanation: "Reverse num to get 625, then reverse 625 to get 526, which equals num." - input: "num = 1800" output: "false" explanation: "Reverse num to get 81, then reverse 81 to get 18, which does not equal num." - input: "num = 0" output: "true" explanation: "Reverse num to get 0, then reverse 0 to get 0, which equals num." explanation: intuition: | At first glance, this problem seems to require implementing a digit reversal function and applying it twice. But let's think deeper about what actually happens during reversal. The key insight is understanding **when information is lost**. When you reverse a number, the only way you lose information is if the original number has **trailing zeros**. These trailing zeros become leading zeros after the first reversal, and leading zeros are dropped (since `0123` is just `123`). Think of it like this: imagine writing a number on a piece of paper and flipping it horizontally. If the number ends in zeros, those zeros move to the front — and we don't write leading zeros! So `1800` becomes `0081` which we write as `81`. Flipping again gives `18`, not `1800`. The only exception is zero itself (`0`), which remains `0` no matter how many times you reverse it. So the question reduces to: **does `num` have trailing zeros?** If yes (and it's not zero), the double reversal won't recover the original. If no, it will. approach: | We solve this with a **simple mathematical observation**: **Step 1: Handle the special case** - If `num` is `0`, return `true` immediately - Zero reversed is zero, so double reversal preserves it   **Step 2: Check for trailing zeros** - A number has trailing zeros if and only if it is divisible by 10 - Check: `num % 10 == 0` - If true, the number has trailing zeros and will lose them on reversal   **Step 3: Return the result** - Return `true` if `num` has no trailing zeros (or is zero) - Return `false` if `num` has trailing zeros   This can be simplified to a single expression: `num == 0 or num % 10 != 0`. common_pitfalls: - title: Actually Implementing Reversal description: | A common first instinct is to implement a digit-reversal function and apply it twice. While this works, it's unnecessarily complex: ```python def reverse(n): result = 0 while n > 0: result = result * 10 + n % 10 n //= 10 return result ``` This is O(log n) time and requires careful handling. The mathematical insight reduces this to O(1). wrong_approach: "Implement reverse function and call twice" correct_approach: "Check if number has trailing zeros" - title: Forgetting Zero is a Special Case description: | Zero ends in zero (`0 % 10 == 0`), but zero reversed is still zero. If you only check for trailing zeros without handling this case, you'll incorrectly return `false` for `num = 0`. The condition `num == 0 or num % 10 != 0` handles this elegantly. wrong_approach: "Only check num % 10 != 0" correct_approach: "Check num == 0 OR num % 10 != 0" - title: Confusing Trailing vs Leading Zeros description: | Leading zeros don't affect a number's value (`007` is just `7`), so they're not the issue. **Trailing zeros** are what get lost because they become leading zeros after reversal. For example: `120` → reverse → `021` = `21` → reverse → `12` ≠ `120`. key_takeaways: - "**Look for the invariant**: Instead of simulating the operation, ask 'when does this operation lose information?'" - "**Trailing zeros are the only information loss**: Reversing a number only loses data when trailing zeros become leading zeros" - "**Mathematical insight beats simulation**: Recognising the pattern gives O(1) instead of O(log n)" - "**Edge cases matter**: Zero is a special case that satisfies `num % 10 == 0` but should return `true`" time_complexity: "O(1). We perform a single modulo operation and comparison." space_complexity: "O(1). We use no additional space beyond the input." solutions: - approach_name: Mathematical Insight is_optimal: true code: | def is_same_after_reversals(num: int) -> bool: # Zero is a special case - reversing 0 gives 0 # Otherwise, check if number has trailing zeros # Trailing zeros become leading zeros after first reversal # and are lost, making double reversal different from original return num == 0 or num % 10 != 0 explanation: | **Time Complexity:** O(1) — Single modulo operation. **Space Complexity:** O(1) — No additional space used. We recognise that the only way a double reversal changes a number is if it has trailing zeros (which become leading zeros and get dropped). Zero itself is the exception since `0` reversed is `0`. - approach_name: Simulation is_optimal: false code: | def is_same_after_reversals(num: int) -> bool: def reverse(n: int) -> int: """Reverse the digits of a non-negative integer.""" result = 0 while n > 0: # Extract last digit and append to result result = result * 10 + n % 10 n //= 10 return result # Apply reversal twice and compare reversed1 = reverse(num) reversed2 = reverse(reversed1) return reversed2 == num explanation: | **Time Complexity:** O(log n) — Each reversal iterates through all digits. **Space Complexity:** O(1) — Only integer variables used. This approach directly simulates the problem statement. While correct, it's more complex than necessary. Understanding why the mathematical approach works is more valuable for interviews.