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.
Example 1:
Input: n = 19 Output: true Explanation: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
Example 2:
Input: n = 2 Output: false
Constraints:
1 <= n <= 231 - 1
The problem asks to determine if a number is a "happy number." A happy number is a number where repeatedly summing the squares of its digits eventually results in 1. If the process enters a cycle without reaching 1, it's not a happy number.
Two approaches are presented to solve this:
Approach 1: Using a Set to Detect Cycles
This approach leverages a Set
(or HashSet
in other languages) to efficiently detect cycles. The algorithm works as follows:
vis
is created to store the numbers encountered during the process.n
is not 1 and hasn't been seen before (not in vis
).n
is calculated and assigned to x
.n
to x
, n
is added to vis
. If n
is already in vis
, it means a cycle has been detected, and the algorithm terminates.n
becomes 1 (happy number) or a cycle is detected (not a happy number).Time Complexity: O(log n). The number of iterations is logarithmic because the number of digits decreases with each iteration. The set operations (insertion and lookup) are generally O(1) on average.
Space Complexity: O(log n) in the worst case because the set vis
could store up to a logarithmic number of unique numbers.
Approach 2: Floyd's Tortoise and Hare Algorithm (Cycle Detection)
This approach employs Floyd's cycle-finding algorithm, also known as the "tortoise and hare" algorithm. It's more efficient in space complexity compared to Approach 1.
slow
and fast
, are initialized to n
and next(n)
respectively, where next(n)
calculates the next number in the sequence.slow
and fast
meet. slow
moves one step at a time, while fast
moves two steps at a time (next(next(fast))
).slow
and fast
meet, it indicates a cycle. The meeting point determines whether the cycle contains 1 or not.slow
(and hence fast
) equals 1 at the meeting point, it's a happy number; otherwise, it's not.Time Complexity: O(log n). The number of iterations is still logarithmic, similar to Approach 1.
Space Complexity: O(1). This approach uses only a constant amount of extra space to store the slow
and fast
pointers.
The code examples for both approaches are provided in the problem description. The Python3 and Java examples are particularly clear. Note that the C code uses a more concise approach for getNext
function. The other languages follow similar logic with minor syntax differences. Approach 2 (Floyd's algorithm) is generally preferred due to its better space complexity.