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

function_signature: "def is_same_after_reversals(num: int) -> bool:"

test_cases:
  visible:
    - input: { num: 526 }
      expected: true
    - input: { num: 1800 }
      expected: false
    - input: { num: 0 }
      expected: true
  hidden:
    - input: { num: 1 }
      expected: true
    - input: { num: 10 }
      expected: false
    - input: { num: 100 }
      expected: false
    - input: { num: 123 }
      expected: true
    - input: { num: 12300 }
      expected: false

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

    &nbsp;

    **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

    &nbsp;

    **Step 3: Return the result**

    - Return `true` if `num` has no trailing zeros (or is zero)
    - Return `false` if `num` has trailing zeros

    &nbsp;

    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.
