Check Happy Number in Java
Problem
A happy number is one where repeatedly replacing it with the sum of the squares of its digits eventually reaches 1 — a number that isn't happy falls into an infinite repeating cycle instead.
Given a number, determine whether it is a happy number.
Java Program
import java.util.HashSet;
import java.util.Set;
public class HappyNumberCheck {
static int digitSquareSum(int num) {
int sum = 0;
while (num > 0) {
int digit = num % 10;
sum += digit * digit;
num /= 10;
}
return sum;
}
public static void main(String[] args) {
int num = 19;
int original = num;
Set<Integer> seen = new HashSet<>();
while (num != 1 && !seen.contains(num)) {
seen.add(num); // remember this value so a repeat can be detected
num = digitSquareSum(num);
}
System.out.println(original + " is a happy number: " + (num == 1));
}
}Output
Core Logic
Repeating the digit-square-sum transformation while tracking every value already seen catches an infinite cycle the moment it would repeat, instead of looping forever.
- 1A
HashSet<Integer>namedseenrecords every value the number has already passed through. - 2The loop continues as long as
numisn't1and hasn't beenseenbefore. - 3Each pass adds the current
numtoseen, then computes the sum of the squares of its digits to get the next value. - 4The loop ends either because
numreached1(happy) or because it repeated a value already inseen(stuck in a cycle, not happy).
19: 19 → 82 → 68 → 100 → 1 — reaching 1 after four steps, so it's reported as happy.Key Point: Without the seen set, an unhappy number like 4 would loop forever — 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 repeats the cycle indefinitely, and the set is what recognizes 4 reappearing as a sign to stop.
Why: Every unhappy number falls into the same known 8-number cycle, so the set only ever needs to grow large enough to detect that repeat, bounded by how many digit-square-sum steps it takes to get there.
Key Concepts
Approach 2: Floyd's Cycle Detection
public class HappyNumberFloyd {
static int digitSquareSum(int num) {
int sum = 0;
while (num > 0) {
int digit = num % 10;
sum += digit * digit;
num /= 10;
}
return sum;
}
public static void main(String[] args) {
int num = 19;
int slow = num, fast = digitSquareSum(num);
// fast advances two steps for every one step slow takes
while (fast != 1 && slow != fast) {
slow = digitSquareSum(slow);
fast = digitSquareSum(digitSquareSum(fast));
}
System.out.println(num + " is a happy number: " + (fast == 1));
}
}
Output
Core Logic
Two pointers moving through the same digit-square-sum sequence at different speeds — one step at a time, and two steps at a time — are guaranteed to meet if the sequence cycles, without needing to remember every value seen.
- 1
slowadvances one digit-square-sum step at a time;fastadvances two steps at a time. - 2If the sequence reaches
1, either pointer landing on1ends the loop with a happy result. - 3If the sequence instead cycles,
fast— moving twice as fast — is guaranteed to lap back around and land on the same value asslowat some point. - 4
slow == fast(once both are past their starting value) confirms a cycle, meaning the number is not happy.
19, both pointers reach 1 before ever meeting elsewhere, confirming a happy number without ever storing a set of past values.Key Point: This is the same tortoise-and-hare technique used to detect cycles in a linked list, applied here to the sequence of digit-square sums instead of node pointers.
Why: Only two running values — slow and fast — are ever kept, instead of a set that grows with every step of the sequence.