Skip to content

72. Happy Number

๐Ÿ”— LeetCode Problem: 202. Happy Number
๐Ÿ“Š Difficulty: Easy
๐Ÿท๏ธ Topics: Hash Table, Math, Two Pointers

Problem Statement

Write an algorithm to determine if a number n is happy.

A happy number is a number defined by the following process:

  • Starting with any positive integer, replace the number by the sum of the squares of its digits.
  • Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
  • Those numbers for which this process ends in 1 are happy.

Return true if n is a happy number, and false if not.

Example 1:

Input: n = 19
Output: true
Explanation:
1ยฒ + 9ยฒ = 1 + 81 = 82
8ยฒ + 2ยฒ = 64 + 4 = 68
6ยฒ + 8ยฒ = 36 + 64 = 100
1ยฒ + 0ยฒ + 0ยฒ = 1 + 0 + 0 = 1

Example 2:

Input: n = 2
Output: false
Explanation:
2ยฒ = 4
4ยฒ = 16
1ยฒ + 6ยฒ = 1 + 36 = 37
3ยฒ + 7ยฒ = 9 + 49 = 58
5ยฒ + 8ยฒ = 25 + 64 = 89
8ยฒ + 9ยฒ = 64 + 81 = 145
1ยฒ + 4ยฒ + 5ยฒ = 1 + 16 + 25 = 42
4ยฒ + 2ยฒ = 16 + 4 = 20
2ยฒ + 0ยฒ = 4 + 0 = 4
(Back to 4, cycle detected!)

Constraints: - 1 <= n <= 2^31 - 1


๐ŸŽจ Visual Understanding

The Problem Visualized

Example 1: n = 19 (Happy Number!)

19 โ†’ 1ยฒ + 9ยฒ = 82
82 โ†’ 8ยฒ + 2ยฒ = 68
68 โ†’ 6ยฒ + 8ยฒ = 100
100 โ†’ 1ยฒ + 0ยฒ + 0ยฒ = 1 โœ“

Reaches 1 โ†’ Happy!
Example 2: n = 2 (Not Happy!)

2 โ†’ 2ยฒ = 4
4 โ†’ 4ยฒ = 16
16 โ†’ 1ยฒ + 6ยฒ = 37
37 โ†’ 3ยฒ + 7ยฒ = 58
58 โ†’ 5ยฒ + 8ยฒ = 89
89 โ†’ 8ยฒ + 9ยฒ = 145
145 โ†’ 1ยฒ + 4ยฒ + 5ยฒ = 42
42 โ†’ 4ยฒ + 2ยฒ = 20
20 โ†’ 2ยฒ + 0ยฒ = 4 โ† Back to 4!

Cycle: 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4
Never reaches 1 โ†’ Not Happy!
Visual representation of cycle:

          4 โ†โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ†“                 โ”‚
         16                20
          โ†“                 โ†‘
         37                42
          โ†“                 โ†‘
         58               145
          โ†“                 โ†‘
         89 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

This is a CYCLE! Just like a linked list cycle!

๐Ÿšจ CRITICAL INSIGHT - This is a Cycle Detection Problem!

The Key Pattern!

This problem is IDENTICAL to detecting a cycle in a linked list!

Instead of:
  node.next โ†’ next node

We have:
  number โ†’ sumOfSquares(number)

The "linked list":
  19 โ†’ 82 โ†’ 68 โ†’ 100 โ†’ 1
  2 โ†’ 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4 (cycle!)

Two possible outcomes:
  1. Reaches 1 (happy) โœ“
  2. Enters a cycle (not happy) โœ—

Use Floyd's Cycle Detection!
  Slow: Computes next once
  Fast: Computes next twice

If they meet at 1: Happy!
If they meet elsewhere: Cycle, not happy!

Why There's Always a Cycle or Reaches 1

Mathematical insight:

For any number, the sum of squares of digits is bounded!

Largest 10-digit number: 9,999,999,999
Sum of squares: 10 ร— 9ยฒ = 810

So any number reduces to โ‰ค 3 digits quickly!

For 3-digit numbers (up to 999):
  Max sum: 9ยฒ + 9ยฒ + 9ยฒ = 243

For 2-digit numbers (up to 99):
  Max sum: 9ยฒ + 9ยฒ = 162

The sequence MUST eventually:
  1. Reach 1 (happy) โœ“
  2. Enter a cycle (not happy) โœ—

There are only so many numbers it can visit!
Eventually, it MUST repeat (cycle) or reach 1!

Common Cycle in Unhappy Numbers

The most common cycle for unhappy numbers:

4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4

Almost all unhappy numbers eventually enter this cycle!

Other possible cycles exist but are rare:
  - Single digit unhappy: 2, 3, 4, 5, 6, 8, 9
  - They all eventually lead to the 4-cycle!

๐ŸŽฏ Approach 1: Hash Set (Tracking Seen Numbers)

The Most Natural Thinking ๐Ÿ’ญ

Core Logic:

Keep track of numbers we've seen
If we see a number again โ†’ cycle!
If we reach 1 โ†’ happy!

Implementation

/**
 * Using HashSet to detect cycle
 * Time: O(log n), Space: O(log n)
 */
public boolean isHappy(int n) {
    Set<Integer> seen = new HashSet<>();

    while (n != 1 && !seen.contains(n)) {
        seen.add(n);
        n = getNext(n);
    }

    return n == 1;
}

// Calculate sum of squares of digits
private int getNext(int n) {
    int sum = 0;

    while (n > 0) {
        int digit = n % 10;
        sum += digit * digit;
        n /= 10;
    }

    return sum;
}

โฐ Time: O(log n) - Number of digits reduces quickly
๐Ÿ’พ Space: O(log n) - Store seen numbers

โœ“ Works well, but uses extra space!


๐ŸŽฏ Approach 2: Floyd's Cycle Detection (Optimal) โญ

Better Approach ๐Ÿ’ก

๐Ÿง  The Core Insight

Treat this as a linked list with cycles!

Instead of node.next, we have getNext(n)

Use fast & slow pointers:
  Slow: computes next once
  Fast: computes next twice

If they meet at 1: Happy!
If they meet at other number: Cycle, not happy!

The Strategy:

Floyd's Algorithm Applied:

1. Initialize slow = n, fast = n
2. Move slow one step: slow = getNext(slow)
3. Move fast two steps: fast = getNext(getNext(fast))
4. If they meet at 1 โ†’ return true
5. If they meet elsewhere โ†’ return false

Space: O(1) - No HashSet needed!

Implementation

/**
 * Floyd's Cycle Detection for Happy Number
 * Time: O(log n), Space: O(1)
 */
public boolean isHappy(int n) {
    int slow = n;
    int fast = n;

    do {
        slow = getNext(slow);              // Move 1 step
        fast = getNext(getNext(fast));     // Move 2 steps
    } while (slow != fast);

    // If they met at 1, it's happy!
    return slow == 1;
}

// Calculate sum of squares of digits
private int getNext(int n) {
    int sum = 0;

    while (n > 0) {
        int digit = n % 10;
        sum += digit * digit;
        n /= 10;
    }

    return sum;
}

โฐ Time: O(log n) - Sequence length is logarithmic
๐Ÿ’พ Space: O(1) - Only two variables!

๐Ÿ” Dry Run

Example 1: n = 19 (Happy Number)

Goal: Check if reaches 1

Initial:
  slow = 19
  fast = 19

Iteration 1:
  slow = getNext(19) = 1ยฒ + 9ยฒ = 82
  fast = getNext(getNext(19))
       = getNext(82)
       = 8ยฒ + 2ยฒ = 68
       = getNext(68)
       = 6ยฒ + 8ยฒ = 100

  slow = 82
  fast = 100
  slow != fast, continue

Iteration 2:
  slow = getNext(82) = 8ยฒ + 2ยฒ = 68
  fast = getNext(getNext(100))
       = getNext(1ยฒ + 0ยฒ + 0ยฒ)
       = getNext(1)
       = 1ยฒ = 1
       = getNext(1)
       = 1ยฒ = 1

  slow = 68
  fast = 1
  slow != fast, continue

Iteration 3:
  slow = getNext(68) = 6ยฒ + 8ยฒ = 100
  fast = getNext(getNext(1))
       = getNext(1)
       = 1
       = getNext(1)
       = 1

  slow = 100
  fast = 1
  slow != fast, continue

Iteration 4:
  slow = getNext(100) = 1ยฒ + 0ยฒ + 0ยฒ = 1
  fast = getNext(getNext(1))
       = getNext(1)
       = 1
       = getNext(1)
       = 1

  slow = 1
  fast = 1
  slow == fast! Loop ends

Return slow == 1? Yes! โœ“
True (Happy number!)

Example 2: n = 2 (Unhappy Number)

Initial:
  slow = 2
  fast = 2

Iteration 1:
  slow = getNext(2) = 2ยฒ = 4
  fast = getNext(getNext(2))
       = getNext(4)
       = 4ยฒ = 16
       = getNext(16)
       = 1ยฒ + 6ยฒ = 37

  slow = 4
  fast = 37
  Continue...

(Several iterations later)

Eventually:
  slow enters cycle: 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4
  fast also in cycle, moving twice as fast

  They meet at some number in the cycle (say 58)

  slow = 58
  fast = 58
  slow == fast! Loop ends

Return slow == 1? No!
False (Not happy!)

๐ŸŽฏ Why This Works - Deep Dive

The Transformation as a "Linked List":
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Think of each number as a "node":
  number โ†’ getNext(number) โ†’ getNext(getNext(number)) โ†’ ...

This creates an implicit "linked list"!

Example: n = 2
  2 โ†’ 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4 (cycle!)

Just like: node1 โ†’ node2 โ†’ ... โ†’ node8 โ†’ node2 (cycle!)

The Two Outcomes:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Outcome 1: Reaches 1
  19 โ†’ 82 โ†’ 68 โ†’ 100 โ†’ 1

  Once at 1: getNext(1) = 1ยฒ = 1
  Stays at 1 forever!

  This is like a cycle of length 1 at node "1"
  Both slow and fast eventually reach 1
  They meet at 1 โœ“

Outcome 2: Enters a cycle (not containing 1)
  2 โ†’ 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4

  Forms a cycle that doesn't include 1
  Both slow and fast enter this cycle
  Fast catches slow inside the cycle
  They meet at some number != 1 โœ—

Floyd's Algorithm Detects Both:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

If happy:
  Both reach 1
  Meet at 1
  Return true โœ“

If not happy:
  Both enter cycle
  Meet at some number != 1
  Return false โœ—

Why Do-While Loop?
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

do {
    slow = getNext(slow);
    fast = getNext(getNext(fast));
} while (slow != fast);

Why not while loop?
  At start: slow = n, fast = n
  They're equal!
  While loop would exit immediately!

Do-while ensures:
  Move first, then check
  Always executes at least once โœ“

Time Complexity:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Key insight: Sequence length is bounded!

For a d-digit number:
  Next value โ‰ค d ร— 81 (since 9ยฒ = 81)

Example: 999 (3 digits)
  Next: 9ยฒ + 9ยฒ + 9ยฒ = 243 (3 digits still)

The sequence converges to small numbers quickly!

Cycle length is also bounded (small)
  Common cycle: 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4
  Length: 8

Total iterations: O(log n)
Each iteration: O(log n) to compute getNext
Overall: O(log n) โœ“

Space: O(1) - Only two variables!

Why getNext Computation is O(log n)

Computing sum of squares of digits:

int getNext(int n) {
    int sum = 0;
    while (n > 0) {
        int digit = n % 10;
        sum += digit * digit;
        n /= 10;
    }
    return sum;
}

Number of iterations = number of digits = logโ‚โ‚€(n)

Example: n = 12345
  5 digits โ†’ 5 iterations
  logโ‚โ‚€(12345) โ‰ˆ 4.09 โ‰ˆ 5 โœ“

So getNext is O(log n)

โš ๏ธ Common Mistakes to Avoid

Mistake 1: Using while instead of do-while

// โŒ WRONG - Exits immediately if slow == fast at start
while (slow != fast) {
    slow = getNext(slow);
    fast = getNext(getNext(fast));
}
// At start, slow = n, fast = n, loop never executes!

// โœ“ CORRECT - Always executes at least once
do {
    slow = getNext(slow);
    fast = getNext(getNext(fast));
} while (slow != fast);

Mistake 2: Checking == 1 inside loop

// โŒ INEFFICIENT - Multiple checks
do {
    slow = getNext(slow);
    fast = getNext(getNext(fast));
    if (slow == 1 || fast == 1) {
        return true;
    }
} while (slow != fast);

// โœ“ CORRECT - Single check after meeting
do {
    slow = getNext(slow);
    fast = getNext(getNext(fast));
} while (slow != fast);
return slow == 1;

Mistake 3: Wrong getNext implementation

// โŒ WRONG - Doesn't handle multiple digits correctly
private int getNext(int n) {
    return n * n;  // Only squares the whole number!
}

// โœ“ CORRECT - Squares each digit
private int getNext(int n) {
    int sum = 0;
    while (n > 0) {
        int digit = n % 10;
        sum += digit * digit;
        n /= 10;
    }
    return sum;
}

Mistake 4: Not initializing both at n

// โŒ WRONG - Different starting points
int slow = n;
int fast = getNext(n);  // Fast starts ahead

// โœ“ CORRECT - Both start at n
int slow = n;
int fast = n;

Mistake 5: Calling getNext with 0

// โŒ POTENTIAL ISSUE - Though it works
// getNext(0) = 0, which creates immediate cycle

// โœ“ BETTER - Handle explicitly if needed
if (n == 0) return false;  // 0 is not happy

๐ŸŽฏ Pattern Recognition

Problem Type: Cycle Detection in Transformation Sequence
Core Pattern: Fast & Slow Pointers (Floyd's Algorithm)

When to Apply:
โœ“ Sequence of transformations
โœ“ Can eventually cycle or reach target
โœ“ No explicit linked list structure
โœ“ Need O(1) space
โœ“ Function creates "next" relationship

Recognition Keywords:
- "Process ends in" (terminal state)
- "Loops endlessly" (cycle)
- "Replace by" (transformation)
- "Repeat the process"
- Number transformations
- Sequence of operations

Similar Problems:
- Linked List Cycle (LC 141) - Explicit linked list
- Find Duplicate Number (LC 287) - Array as linked list
- Circular Array Loop (LC 457) - Array with cycles

Key Components:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 1. Transformation function (getNext)      โ”‚
โ”‚ 2. Two outcomes: target or cycle          โ”‚
โ”‚ 3. Fast & slow pointers                   โ”‚
โ”‚ 4. Meet at target or in cycle             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

This shows Floyd's algorithm works beyond linked lists!

๐Ÿง  Interview Strategy

Step 1: "This is cycle detection, not explicit linked list"
Step 2: "Use Floyd's algorithm with transformation function"
Step 3: "If meet at 1: happy; else: cycle, not happy"
Step 4: "O(log n) time, O(1) space"

Key Points to Mention:
- Each number โ†’ next number via sum of squares
- Creates implicit "linked list"
- Two outcomes: reach 1 or enter cycle
- Use fast & slow pointers
- Do-while loop (both start at n)
- Meet at 1 โ†’ happy, else โ†’ not happy
- Time: O(log n), Space: O(1)
- Alternative: HashSet O(log n) space

Why This Approach?
"I recognize this as a cycle detection problem. Each number
transforms to the next via sum of squares of digits, creating
an implicit linked list. It either reaches 1 (happy) or enters
a cycle (not happy). I'll use Floyd's cycle detection with two
pointers moving at different speeds. When they meet, if they're
at 1, the number is happy. Otherwise, they met in a cycle."

Why Do-While?
"Since both pointers start at n, they're initially equal. A
while loop would exit immediately. The do-while ensures we
move both pointers at least once before checking if they meet."

Edge Cases to Mention:
โœ“ n = 1 (already happy)
โœ“ n = 2 (enters cycle immediately)
โœ“ Small numbers (quick convergence)
โœ“ Large numbers (rapid reduction)

๐Ÿ“ Quick Revision Notes

๐ŸŽฏ Core Concept:

Happy Number: Each number โ†’ sum of squares of digits. Reaches 1 (happy โœ“) or enters cycle (not happy โœ—). Use Floyd's algorithm! Slow: next once, Fast: next twice. Do-while loop (both start at n). If meet at 1: happy. Else: cycle. O(log n) time, O(1) space!

โšก Quick Implementation:

class Test {
  public boolean isHappy(int n) {
    // // Approach 1 - hashset 
    // // TC: O(log n) and SC: O(log n)
    // HashSet<Integer> set = new HashSet<>();

    // while (n != 1 && !set.contains(n)) {
    //   set.add(n); // add the incoming number
    //   int curr = n;
    //   int squaresSum = 0;

    //   // find the sum of squares of number.
    //   while (curr > 0) {
    //     int mod = curr % 10;
    //     squaresSum += Math.pow(mod, 2);
    //     curr = curr / 10;
    //   }

    //   n = squaresSum;      
    // }

    // return n == 1;

    // Approach 2 - using Floyd Algorithm
    // TC: O(log n) and SC: O(1)
    // Almost same as above. Instead of finding next num one at a time, we
    // find 2 next numbers at a time. This gets equivalent to fast and slow
    // pointers. When fast pointer lap on the slow pointer, cycle gets
    // detected and the number is not happy.
    int slow = n;
    int fast = n;
    while (fast != 1) { // loop till it becomes unhappy.
      System.out.println("slow: "+slow+" and fast: "+fast);
      slow = getSumOfSquares(slow);
      fast = getSumOfSquares(getSumOfSquares(fast));      
      System.out.println("sslow: "+slow+" and fast: "+fast);

      // break once cycle gets detected or
      // when happy number found (edge case when both slow and fast are equal)
      if(slow == fast && fast != 1) {
        return false;
      }
    }

    return true;
  }

  private int getSumOfSquares(int n) {
    int curr = n;
    int squaresSum = 0;

    // find the sum of squares of number.
    while (curr > 0) {
      int mod = curr % 10;
      squaresSum += Math.pow(mod, 2);
      curr = curr / 10;
    }

    return squaresSum;
  }

  public static void main(String[] args) {
    Test t = new Test();
    System.out.println(t.isHappy(19) == true); // T
    System.out.println(t.isHappy(2) == false); // F
    System.out.println(t.isHappy(1) == true); // T
    System.out.println(t.isHappy(2) == false); // F
    System.out.println(t.isHappy(7) == true); // T
    System.out.println(t.isHappy(116) == false); // F
    System.out.println(t.isHappy(10) == true); // T
  }
}

๐Ÿ”‘ Key Insights:

  • Pattern: Fast & Slow Pointers on transformations
  • Transform: n โ†’ sum of squares of digits
  • Implicit List: Each number โ†’ next number
  • Two Outcomes: Reach 1 (happy) or cycle (not happy)
  • Do-While: Both start at n, need to move first
  • Meet at 1: Happy! โœ“
  • Meet elsewhere: Cycle, not happy โœ—
  • getNext: O(log n) - number of digits
  • Time: O(log n), Space: O(1)

๐ŸŽช Memory Aid:

"Sum squares of digits! Reach 1 or cycle! Floyd detects both!"
Think: "Implicit linked list with transformations!" ๐Ÿ”„

๐Ÿ’ก The Key Insight:

This is a disguised linked list cycle problem!

Each number "points to" its next:
  n โ†’ getNext(n) โ†’ getNext(getNext(n)) โ†’ ...

Just like:
  node โ†’ node.next โ†’ node.next.next โ†’ ...

Floyd's algorithm works on ANY sequence!

โš ๏ธ Critical Details:

1. Transform: Sum of squares of each digit
2. getNext: Extract digits with % 10, divide by 10
3. Do-While: MUST use (not while)
4. Why? Both start equal, need to move first
5. Meet at 1: Return true (happy)
6. Meet elsewhere: Return false (cycle)
7. Common cycle: 4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4
8. Bounded: Sequences converge quickly

๐Ÿ”ฅ The getNext Function:

n = 19

Extract digits and square:
  19 % 10 = 9 โ†’ 9ยฒ = 81
  19 / 10 = 1

  1 % 10 = 1 โ†’ 1ยฒ = 1
  1 / 10 = 0 (done)

Sum: 81 + 1 = 82 โœ“

๐Ÿ’ก Why Do-While:

Initial state:
  slow = 19
  fast = 19

If using while (slow != fast):
  19 != 19? No! Loop exits immediately โœ—

Using do-while:
  Move first, THEN check
  Always executes at least once โœ“

After first iteration:
  slow = 82
  fast = 100
  Now they're different, loop continues โœ“

๐ŸŽฏ Common Unhappy Cycle:

Most unhappy numbers end up in this cycle:

4 โ†’ 16 โ†’ 37 โ†’ 58 โ†’ 89 โ†’ 145 โ†’ 42 โ†’ 20 โ†’ 4

Examples:
  2 โ†’ 4 โ†’ (enters cycle)
  3 โ†’ 9 โ†’ 81 โ†’ 65 โ†’ 61 โ†’ 37 โ†’ (in cycle)
  5 โ†’ 25 โ†’ 29 โ†’ 85 โ†’ 89 โ†’ (in cycle)

Almost all unhappy numbers eventually
reach this 8-number cycle!

๐Ÿงช Edge Cases

Case 1: Already happy

Input: n = 1
Output: true
(1ยฒ = 1, stays at 1)

Case 2: Simple unhappy

Input: n = 2
Output: false
(2 โ†’ 4 โ†’ 16 โ†’ ... โ†’ cycle)

Case 3: Large happy number

Input: n = 7
Output: true
(7 โ†’ 49 โ†’ 97 โ†’ 130 โ†’ 10 โ†’ 1)

Case 4: Two digits happy

Input: n = 19
Output: true
(19 โ†’ 82 โ†’ 68 โ†’ 100 โ†’ 1)

Case 5: Three digits unhappy

Input: n = 116
Output: false
(Enters cycle)

All handled correctly! โœ“


  • Linked List Cycle (LC 141) - Explicit linked list
  • Find Duplicate Number (LC 287) - Array as implicit list
  • Circular Array Loop (LC 457) - Array with indices

Happy practicing! ๐ŸŽฏ

Note: This beautifully demonstrates Floyd's algorithm works on ANY sequence, not just linked lists! The transformation function creates an implicit "linked list" structure! ๐Ÿ”„