Problem Statement
You are given a positive integer n. Replace the number by the sum of the squares of its digits, and repeat the process until:
- It becomes
1(which means it’s a happy number), or - It loops endlessly in a cycle (not a happy number).
Return true if n is a happy number. Otherwise, return false.
What is a Happy Number?
A happy number is a number that eventually reaches 1 when you repeatedly replace it by the sum of the squares of its digits.
Example:
Let’s take n = 19:
- 12+92=1+81=82
- 82+22=64+4=68
- 62+82=36+64=100
- 12+02+02=1 → Happy number!
Now take n = 6:
- Eventually, the process falls into a loop and never reaches 1. So,
6is not a happy number.
Solution 1: Using a HashSet to Detect Loops
Intuition:
To detect if a number is entering a cycle (i.e., we’ve seen it before), we can store previously seen numbers in a HashSet.
import java.util.HashSet;
import java.util.Set;
public class HappyNumber {
public boolean isHappy(int n) {
if (n <= 0) return false;
Set<Integer> seen = new HashSet<>();
while (n != 1) {
if (seen.contains(n)) {
return false; // loop detected
}
seen.add(n);
n = sumOfSquares(n);
}
return true;
}
private int sumOfSquares(int num) {
int sum = 0;
while (num > 0) {
int digit = num % 10;
sum += digit * digit;
num /= 10;
}
return sum;
}
}
Time & Space Complexity:
- Time: O(log n) per digit sum operation × number of steps
- Space: O(k), where k is the size of the cycle or number of unique intermediate results
Solution 2: Floyd’s Cycle Detection (Fast and Slow Pointers)
Intuition:
Inspired by detecting cycles in linked lists. Use two variables:
- Slow pointer: moves one step at a time
- Fast pointer: moves two steps at a time
If there’s a cycle (i.e., it’s not a happy number), they’ll eventually meet at the same number other than 1.
public class HappyNumber {
public boolean isHappy(int n) {
if (n <= 0) return false;
int slow = n;
int fast = sumOfSquares(n);
while (fast != 1 && slow != fast) {
slow = sumOfSquares(slow);
fast = sumOfSquares(sumOfSquares(fast));
}
return fast == 1;
}
private int sumOfSquares(int num) {
int sum = 0;
while (num > 0) {
int digit = num % 10;
sum += digit * digit;
num /= 10;
}
return sum;
}
}
Explaination
Step 1: Handle invalid inputs
if (n <= 0) return false;
Happy numbers are only defined for positive integers, so we immediately return false for non-positive inputs (0 or negative numbers).
Step 2: Initialize two pointers
int slow = n; int fast = sumOfSquares(n);
- We set
slowto the original numbern. - We set
fastto the sum of the squares of the digits ofn(i.e., one step ahead ofslow).
Step 3: Run the cycle detection loop
while (fast != 1 && slow != fast) {
slow = sumOfSquares(slow);
fast = sumOfSquares(sumOfSquares(fast));
}
This loop continues until:
fast == 1→ the number is happyslow == fast→ a cycle is detected (i.e., the number is not happy)
Here’s what happens:
slowmoves one step at a time (sumOfSquares(slow))fastmoves two steps at a time (sumOfSquares(sumOfSquares(fast)))
This is exactly like detecting a cycle in a linked list using two pointers: a slow and a fast one.
Time & Space Complexity:
- Time: Same as the previous method
- Space: O(1), constant extra space
Edge Cases
n <= 0→ Returnfalse(not a natural number)n == 1→ Returntrue- Negative numbers → Not valid happy numbers
