Skip to content
  • Math & Geometry · Sheet 150

Happy Number

LearnViaNotes @learnvianotes· 3 min read

Difficulty: Easy · LeetCode 202

Problem

A number is happy if repeatedly replacing it with the sum of the squares of its digits eventually reaches 1. Return True if the number is happy.

Understanding the problem

An unhappy number never reaches 1 — it enters a cycle. The process of digit-squaring is a value transformation that either terminates at 1 or loops. Floyd's cycle detection handles both cases without storing visited states.

Intuition

Model the transformation as a linked-list-style sequence. A happy number converges to the cycle 1 → 1 → …; an unhappy number enters another cycle. Floyd's slow/fast pointers detect the cycle in O(1) space.

Approach

  1. Define next_number(num): extract digits, return sum of their squares.

  2. Initialize slow = n, fast = next_number(n).

  3. While fast != 1 and slow != fast: advance slow one step, fast two steps.

  4. Return fast == 1.

Naive Solution — Brute Force

Keep a seen set; stop when 1 is reached or a repeated value is detected.

Python
class Solution:
    def isHappy(self, n):
        seen = set()

        while n != 1:
            if n in seen:
                return False

            seen.add(n)

            total = 0

            while n > 0:
                digit = n % 10
                total += digit * digit
                n //= 10

            n = total

        return True
C++
class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> seen;

        while (n != 1) {
            if (seen.count(n)) {
                return false;
            }

            seen.insert(n);

            int total = 0;

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

            n = total;
        }

        return true;
    }
};
Java
class Solution {
    public boolean isHappy(int n) {
        Set<Integer> seen = new HashSet<>();

        while (n != 1) {
            if (seen.contains(n)) {
                return false;
            }

            seen.add(n);

            int total = 0;

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

            n = total;
        }

        return true;
    }
}
JavaScript
var isHappy = function(n) {
    const seen = new Set();

    while (n !== 1) {
        if (seen.has(n)) {
            return false;
        }

        seen.add(n);

        let total = 0;

        while (n > 0) {
            const digit = n % 10;
            total += digit * digit;
            n = Math.floor(n / 10);
        }

        n = total;
    }

    return true;
};

Time: O(log n) — bounded digit states · Space: O(log n)

Optimized Code (Python 3)

Python
class Solution:
    def isHappy(self, n):

        def next_number(num):
            total = 0

            while num > 0:
                digit = num % 10
                total += digit * digit
                num //= 10

            return total

        slow = n
        fast = next_number(n)

        while fast != 1 and slow != fast:
            slow = next_number(slow)
            fast = next_number(next_number(fast))

        return fast == 1
C++
class Solution {
public:
    bool isHappy(int n) {
        int slow = n;
        int fast = nextNumber(n);

        while (fast != 1 && slow != fast) {
            slow = nextNumber(slow);
            fast = nextNumber(nextNumber(fast));
        }

        return fast == 1;
    }

private:
    int nextNumber(int num) {
        int total = 0;

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

        return total;
    }
};
Java
class Solution {
    public boolean isHappy(int n) {
        int slow = n;
        int fast = nextNumber(n);

        while (fast != 1 && slow != fast) {
            slow = nextNumber(slow);
            fast = nextNumber(nextNumber(fast));
        }

        return fast == 1;
    }

    private int nextNumber(int num) {
        int total = 0;

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

        return total;
    }
}
JavaScript
var isHappy = function(n) {
    const nextNumber = (num) => {
        let total = 0;

        while (num > 0) {
            const digit = num % 10;
            total += digit * digit;
            num = Math.floor(num / 10);
        }

        return total;
    };

    let slow = n;
    let fast = nextNumber(n);

    while (fast !== 1 && slow !== fast) {
        slow = nextNumber(slow);
        fast = nextNumber(nextNumber(fast));
    }

    return fast === 1;
};

Time: O(log n) — bounded digit states · Space: O(1)

Takeaway

Pattern — Repeated value transformation → cycle or termination → Floyd's Cycle Detection (same family as LC 141)

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report