class Solution:
def isHappy(self, n: int) -> bool:
def get_next(number):
total_sum = 0
while number > 0:
digit = number % 10
total_sum += digit * digit
number //= 10
return total_sum
seen = set()
while n != 1 and n not in seen:
seen.add(n)
n = get_next(n)
return n == 1
class Solution {
public:
bool isHappy(int n) {
auto get_next = [](int number) {
int total_sum = 0;
while (number > 0) {
int digit = number % 10;
total_sum += digit * digit;
number /= 10;
}
return total_sum;
};
std::unordered_set<int> seen;
while (n != 1 && seen.find(n) == seen.end()) {
seen.insert(n);
n = get_next(n);
}
return n == 1;
}
};
import java.util.HashSet;
class Solution {
public boolean isHappy(int n) {
HashSet<Integer> seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getNext(n);
}
return n == 1;
}
private int getNext(int number) {
int totalSum = 0;
while (number > 0) {
int digit = number % 10;
totalSum += digit * digit;
number /= 10;
}
return totalSum;
}
}
var isHappy = function(n) {
const getNext = (number) => {
let totalSum = 0;
while (number > 0) {
let digit = number % 10;
totalSum += digit * digit;
number = Math.floor(number / 10);
}
return totalSum;
};
const seen = new Set();
while (n !== 1 && !seen.has(n)) {
seen.add(n);
n = getNext(n);
}
return n === 1;
};
The "Happy Number" problem asks you to determine if a given positive integer n
is a "happy number." A happy number is defined as follows:
n
.1
(where it will stay), or it loops endlessly in a cycle that does not include 1
.1
, the number is "happy." Otherwise, it is "unhappy."
The function should return true
if n
is a happy number, and false
otherwise.
To solve the Happy Number problem, we need to simulate the process described and determine if it ends at 1
or falls into a cycle. The naive approach is to keep applying the digit-squaring process until we either reach 1
or notice that we are repeating numbers (which means we are in a loop).
The key challenge is cycle detection. If we don't keep track of previously seen numbers, we might loop forever. By storing numbers we've already computed, we can detect cycles efficiently.
This is similar to the "tortoise and hare" approach for cycle detection in linked lists, but using a set (hash table) is simpler and just as effective here.
Here’s how we can solve the problem step by step:
1
and hasn't been seen before, add it to the set.
19
, its digits are 1
and 9
, so the next number is 1^2 + 9^2 = 82
.
1
, return true
; otherwise, return false
.
We use a set for fast O(1) lookups to track previously seen numbers and prevent infinite loops.
Let's walk through an example with n = 19
:
19
. Digits: 1
and 9
. 1^2 + 9^2 = 1 + 81 = 82
82
. Digits: 8
and 2
. 8^2 + 2^2 = 64 + 4 = 68
68
. Digits: 6
and 8
. 6^2 + 8^2 = 36 + 64 = 100
100
. Digits: 1
, 0
, 0
. 1^2 + 0^2 + 0^2 = 1 + 0 + 0 = 1
1
! So, 19
is a happy number.
If at any point we got a number we had already seen, we would stop and return false
because that means we are in a cycle.
The Happy Number problem is a classic example of cycle detection in iterative processes. By tracking previously seen numbers with a set, we efficiently avoid infinite loops and determine whether a number is happy. The approach is simple, elegant, and leverages hash-based lookups for performance. The key insight is to recognize that the process will always fall into a cycle or reach 1, making the set-based solution both effective and easy to implement.