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
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We want to determine if a number is happy by repeatedly summing the squares of its digits. The brute force approach involves simply following this process for a number and keeping track of the numbers we've seen to avoid getting stuck in a cycle.
Here's how the algorithm would work step-by-step:
def is_happy_number(number): seen_numbers = set()
while True:
sum_of_squared_digits = 0
temporary_number = number
while temporary_number > 0:
digit = temporary_number % 10
sum_of_squared_digits += digit ** 2
temporary_number //= 10
if sum_of_squared_digits == 1:
return True
# Check to see if we have found a loop
if sum_of_squared_digits in seen_numbers:
return False
# Adding the current sum to seen numbers set
seen_numbers.add(sum_of_squared_digits)
number = sum_of_squared_digits
The key idea is to recognize that if a number is not happy, the process will eventually enter a cycle. We can detect this cycle by remembering numbers we've already seen. If we encounter a number we've seen before, we know we're in a cycle and the number is not happy.
Here's how the algorithm would work step-by-step:
def is_happy(number):
seen_numbers = set()
while number != 1:
sum_of_squared_digits = 0
temp_number = number
while temp_number > 0:
digit = temp_number % 10
sum_of_squared_digits += digit ** 2
temp_number //= 10
# If we've seen this number before, it's a cycle.
if sum_of_squared_digits in seen_numbers:
return False
# Store the number to detect cycles.
seen_numbers.add(sum_of_squared_digits)
number = sum_of_squared_digits
return True
Case | How to Handle |
---|---|
Input is a negative number | Return false immediately as the problem specifies a process starting with the input number, and the squaring of negative digits will eventually lead to the same number sequence as its positive counterpart, if the positive counter part ends up in an infinite loop. |
Input is zero | Return false because the sum of squares of digits will remain zero and never reach 1. |
Input is 1 | Return true immediately because the number is already 1. |
Large input that potentially causes integer overflow when squaring the digits | Use a data type with a larger range to avoid overflow or apply modulo operation if needed, but in this problem, the sum of squares of digits reduces the integer, so it wont overflow. |
Number leads to a cycle not including 1 | Use a set to store previously seen numbers and return false if the current number is already in the set. |
Single-digit number other than 1 | The sum of squares will be the square of the number, so using the cycle detection mechanism by set will cause it to terminate if it isn't 1. |
Number with many digits which could increase space complexity if cycle detection is inefficient | Cycle detection should be efficient (e.g., using a hash set), as even very large numbers will quickly reduce to smaller numbers. |
Very large number of iterations before a cycle is found or 1 is reached | Cycle detection is still crucial to prevent infinite loops, regardless of the iteration count. |