Write an algorithm to determine if a number n
is happy.
A happy number is a number defined by the following process:
Return true
if n
is a happy number, and false
if not.
For example:
Example 1:
Input: n = 19
Output: true
Explanation:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
Example 2:
Input: n = 2
Output: false
What are the time and space complexities of your solution?
Determine if a number n
is a happy number. A happy number is defined by repeatedly replacing the number by the sum of the squares of its digits until it equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Return true
if n
is a happy number, and false
if not.
A brute force approach would involve simulating the process as described in the problem and checking if we encounter a cycle. We can keep track of the numbers we have seen so far using a set. If we encounter a number that is already in the set, it means we are in a cycle.
n
is 1 or we find a cycle.n
.true
.false
.n
with the new number.def isHappy_brute_force(n: int) -> bool:
seen = set()
while n != 1 and n not in seen:
seen.add(n)
sum_of_squares = 0
while n > 0:
digit = n % 10
sum_of_squares += digit ** 2
n //= 10
n = sum_of_squares
return n == 1
An optimized approach can use Floyd's cycle-finding algorithm (also known as the "tortoise and hare" algorithm) to detect cycles. Instead of storing all visited numbers in a set, we use two pointers, slow
and fast
. The slow
pointer moves one step at a time, while the fast
pointer moves two steps at a time. If there is a cycle, the two pointers will eventually meet. If there is no cycle, both pointers will eventually reach 1.
slow
and fast
, both starting at n
.slow
one step at a time and fast
two steps at a time.fast
becomes 1, return true
.slow
and fast
meet, return false
.def isHappy(n: int) -> bool:
def get_next(n):
sum_of_squares = 0
while n > 0:
digit = n % 10
sum_of_squares += digit ** 2
n //= 10
return sum_of_squares
slow = n
fast = get_next(n)
while fast != 1 and slow != fast:
slow = get_next(slow)
fast = get_next(get_next(fast))
return fast == 1
n
because, on average, the number of digits reduces with each sum of square computation.n = 1
: Should return true
immediately.n = 2
: Should return false
as it enters a cycle.n
is a large number: The algorithm should handle large numbers without overflowing.